@yoooclaw/phone-notifications 1.10.3 → 1.10.4

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
@@ -206,9 +206,38 @@ var init_credentials = __esm({
206
206
  });
207
207
 
208
208
  // src/env.ts
209
+ function writeDotEnv(key, value) {
210
+ const path2 = resolveStateFile(".env");
211
+ (0, import_node_fs9.mkdirSync)((0, import_node_path8.dirname)(path2), { recursive: true });
212
+ const existing = (0, import_node_fs9.existsSync)(path2) ? (0, import_node_fs9.readFileSync)(path2, "utf-8") : "";
213
+ const lines = existing.split("\n");
214
+ const prefix = `${key}=`;
215
+ const idx = lines.findIndex((l) => l.startsWith(prefix));
216
+ const newLine = `${prefix}${value}`;
217
+ if (idx >= 0) {
218
+ lines[idx] = newLine;
219
+ } else {
220
+ if (existing && !existing.endsWith("\n")) lines.push("");
221
+ lines.push(newLine);
222
+ }
223
+ (0, import_node_fs9.writeFileSync)(path2, lines.join("\n"), "utf-8");
224
+ }
225
+ function readDotEnv() {
226
+ const path2 = resolveStateFile(".env");
227
+ if (!(0, import_node_fs9.existsSync)(path2)) return {};
228
+ return Object.fromEntries(
229
+ (0, import_node_fs9.readFileSync)(path2, "utf-8").split("\n").flatMap((line) => {
230
+ const eq = line.indexOf("=");
231
+ if (eq < 1) return [];
232
+ return [[line.slice(0, eq).trim(), line.slice(eq + 1).trim()]];
233
+ })
234
+ );
235
+ }
209
236
  function loadEnvName() {
210
- const fromEnvVar = process.env.OPENCLAW_ENV?.trim();
237
+ const fromEnvVar = process.env.PHONE_NOTIFICATIONS_ENV?.trim();
211
238
  if (fromEnvVar && VALID_ENVS.has(fromEnvVar)) return fromEnvVar;
239
+ const fromDotEnv = readDotEnv()["PHONE_NOTIFICATIONS_ENV"]?.trim();
240
+ if (fromDotEnv && VALID_ENVS.has(fromDotEnv)) return fromDotEnv;
212
241
  const { env } = readCredentials();
213
242
  if (env && VALID_ENVS.has(env)) return env;
214
243
  return "production";
@@ -219,7 +248,7 @@ function saveEnvName(env) {
219
248
  `\u65E0\u6548\u7684\u73AF\u5883\u540D\u79F0: ${env}\uFF0C\u53EF\u9009\u503C: ${[...VALID_ENVS].join(", ")}`
220
249
  );
221
250
  }
222
- writeCredentials({ ...readCredentials(), env });
251
+ writeDotEnv("PHONE_NOTIFICATIONS_ENV", env);
223
252
  }
224
253
  function getEnvUrls(env) {
225
254
  return ENV_CONFIG[env ?? loadEnvName()];
@@ -227,11 +256,14 @@ function getEnvUrls(env) {
227
256
  function getAvailableEnvs() {
228
257
  return Object.keys(ENV_CONFIG);
229
258
  }
230
- var ENV_CONFIG, VALID_ENVS;
259
+ var import_node_fs9, import_node_path8, ENV_CONFIG, VALID_ENVS;
231
260
  var init_env = __esm({
232
261
  "src/env.ts"() {
233
262
  "use strict";
263
+ import_node_fs9 = require("fs");
264
+ import_node_path8 = require("path");
234
265
  init_credentials();
266
+ init_host();
235
267
  ENV_CONFIG = {
236
268
  development: {
237
269
  lightApiUrl: "https://openclaw-service-dev.yoooclaw.com/api/message/tob/sendMessage",
@@ -500,20 +532,20 @@ function selectModelByMemory(availableGB, isAppleSilicon = false) {
500
532
  return "tiny";
501
533
  }
502
534
  function resolveModelsDir(dataDir) {
503
- const dir = (0, import_node_path21.join)(dataDir, WHISPER_MODELS_DIR);
504
- (0, import_node_fs25.mkdirSync)(dir, { recursive: true });
535
+ const dir = (0, import_node_path22.join)(dataDir, WHISPER_MODELS_DIR);
536
+ (0, import_node_fs26.mkdirSync)(dir, { recursive: true });
505
537
  return dir;
506
538
  }
507
539
  function resolveBinDir(dataDir) {
508
- const dir = (0, import_node_path21.join)(dataDir, WHISPER_BIN_DIR);
509
- (0, import_node_fs25.mkdirSync)(dir, { recursive: true });
540
+ const dir = (0, import_node_path22.join)(dataDir, WHISPER_BIN_DIR);
541
+ (0, import_node_fs26.mkdirSync)(dir, { recursive: true });
510
542
  return dir;
511
543
  }
512
544
  function isModelDownloaded(modelsDir, modelSize) {
513
- const modelPath = (0, import_node_path21.join)(modelsDir, MODEL_FILENAMES[modelSize]);
514
- if (!(0, import_node_fs25.existsSync)(modelPath)) return false;
545
+ const modelPath = (0, import_node_path22.join)(modelsDir, MODEL_FILENAMES[modelSize]);
546
+ if (!(0, import_node_fs26.existsSync)(modelPath)) return false;
515
547
  try {
516
- const stat = (0, import_node_fs25.statSync)(modelPath);
548
+ const stat = (0, import_node_fs26.statSync)(modelPath);
517
549
  const expectedSize = MODEL_DISK_SIZES[modelSize];
518
550
  return stat.size >= expectedSize * 0.8;
519
551
  } catch {
@@ -522,7 +554,7 @@ function isModelDownloaded(modelsDir, modelSize) {
522
554
  }
523
555
  async function downloadModel(modelsDir, modelSize, logger, modelSource, mirrorUrl) {
524
556
  const filename = MODEL_FILENAMES[modelSize];
525
- const modelPath = (0, import_node_path21.join)(modelsDir, filename);
557
+ const modelPath = (0, import_node_path22.join)(modelsDir, filename);
526
558
  if (isModelDownloaded(modelsDir, modelSize)) {
527
559
  logger.info(`[whisper-local] \u6A21\u578B\u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u4E0B\u8F7D: ${filename}`);
528
560
  return { ok: true, modelPath };
@@ -588,7 +620,7 @@ async function probeUrl(url, logger) {
588
620
  async function downloadFromUrl(url, modelPath, logger) {
589
621
  const tmpPath = `${modelPath}.downloading`;
590
622
  try {
591
- (0, import_node_fs25.mkdirSync)((0, import_node_path21.dirname)(modelPath), { recursive: true });
623
+ (0, import_node_fs26.mkdirSync)((0, import_node_path22.dirname)(modelPath), { recursive: true });
592
624
  const controller = new AbortController();
593
625
  const timer = setTimeout(() => controller.abort(), 30 * 60 * 1e3);
594
626
  try {
@@ -604,7 +636,7 @@ async function downloadFromUrl(url, modelPath, logger) {
604
636
  return { ok: false, modelPath, error: "\u6A21\u578B\u4E0B\u8F7D\u5931\u8D25: \u54CD\u5E94\u4F53\u4E3A\u7A7A" };
605
637
  }
606
638
  const contentLength = Number(res.headers.get("content-length") ?? 0);
607
- const writeStream = (0, import_node_fs25.createWriteStream)(tmpPath);
639
+ const writeStream = (0, import_node_fs26.createWriteStream)(tmpPath);
608
640
  const readable = import_node_stream2.Readable.fromWeb(res.body);
609
641
  let downloaded = 0;
610
642
  let lastLogPercent = 0;
@@ -626,14 +658,14 @@ async function downloadFromUrl(url, modelPath, logger) {
626
658
  }
627
659
  const { renameSync: renameSync2 } = await import("fs");
628
660
  renameSync2(tmpPath, modelPath);
629
- const fileSize = (0, import_node_fs25.statSync)(modelPath).size;
661
+ const fileSize = (0, import_node_fs26.statSync)(modelPath).size;
630
662
  logger.info(
631
- `[whisper-local] \u6A21\u578B\u4E0B\u8F7D\u5B8C\u6210: ${(0, import_node_path21.basename)(modelPath)} (${formatBytes2(fileSize)})`
663
+ `[whisper-local] \u6A21\u578B\u4E0B\u8F7D\u5B8C\u6210: ${(0, import_node_path22.basename)(modelPath)} (${formatBytes2(fileSize)})`
632
664
  );
633
665
  return { ok: true, modelPath };
634
666
  } catch (err) {
635
667
  try {
636
- if ((0, import_node_fs25.existsSync)(tmpPath)) (0, import_node_fs25.unlinkSync)(tmpPath);
668
+ if ((0, import_node_fs26.existsSync)(tmpPath)) (0, import_node_fs26.unlinkSync)(tmpPath);
637
669
  } catch {
638
670
  }
639
671
  const msg = err?.name === "AbortError" ? "\u6A21\u578B\u4E0B\u8F7D\u8D85\u65F6\uFF0830 \u5206\u949F\uFF09" : err?.message ?? String(err);
@@ -645,8 +677,8 @@ function findWhisperBinary(dataDir, logger) {
645
677
  const binDir = resolveBinDir(dataDir);
646
678
  const binNames = (0, import_node_os4.platform)() === "win32" ? ["whisper-cli.exe", "whisper.exe", "main.exe"] : ["whisper-cli", "whisper", "main"];
647
679
  for (const name of binNames) {
648
- const binPath = (0, import_node_path21.join)(binDir, name);
649
- if ((0, import_node_fs25.existsSync)(binPath)) {
680
+ const binPath = (0, import_node_path22.join)(binDir, name);
681
+ if ((0, import_node_fs26.existsSync)(binPath)) {
650
682
  logger.info(`[whisper-local] \u627E\u5230\u672C\u5730\u4E8C\u8FDB\u5236: ${binPath}`);
651
683
  return binPath;
652
684
  }
@@ -697,7 +729,7 @@ async function transcribeWithWhisperLocal(audioFilePath, localConfig, dataDir, l
697
729
  return { ok: false, error: `\u6A21\u578B\u4E0B\u8F7D\u5931\u8D25: ${downloadResult.error}` };
698
730
  }
699
731
  }
700
- const modelPath = (0, import_node_path21.join)(modelsDir, MODEL_FILENAMES[modelSize]);
732
+ const modelPath = (0, import_node_path22.join)(modelsDir, MODEL_FILENAMES[modelSize]);
701
733
  let inputPath = audioFilePath;
702
734
  let tmpWavPath = null;
703
735
  const actualFmt = detectAudioFormat(audioFilePath);
@@ -749,10 +781,10 @@ async function transcribeWithWhisperLocal(audioFilePath, localConfig, dataDir, l
749
781
  logger.info(`[whisper-local] \u8F6C\u5199\u8017\u65F6: ${Math.round(elapsed / 1e3)}s`);
750
782
  const jsonPath = inputPath + ".json";
751
783
  let jsonContent;
752
- if ((0, import_node_fs25.existsSync)(jsonPath)) {
753
- jsonContent = (0, import_node_fs25.readFileSync)(jsonPath, "utf-8");
784
+ if ((0, import_node_fs26.existsSync)(jsonPath)) {
785
+ jsonContent = (0, import_node_fs26.readFileSync)(jsonPath, "utf-8");
754
786
  try {
755
- (0, import_node_fs25.unlinkSync)(jsonPath);
787
+ (0, import_node_fs26.unlinkSync)(jsonPath);
756
788
  } catch {
757
789
  }
758
790
  } else {
@@ -830,10 +862,10 @@ function getPhysicalCoreCount() {
830
862
  }
831
863
  function detectAudioFormat(filePath) {
832
864
  try {
833
- const fd = (0, import_node_fs25.openSync)(filePath, "r");
865
+ const fd = (0, import_node_fs26.openSync)(filePath, "r");
834
866
  const buf = Buffer.alloc(12);
835
- (0, import_node_fs25.readSync)(fd, buf, 0, 12, 0);
836
- (0, import_node_fs25.closeSync)(fd);
867
+ (0, import_node_fs26.readSync)(fd, buf, 0, 12, 0);
868
+ (0, import_node_fs26.closeSync)(fd);
837
869
  const header = buf.toString("ascii", 0, 4);
838
870
  const header8 = buf.toString("ascii", 0, 8);
839
871
  if (header === "RIFF" && buf.toString("ascii", 8, 12) === "WAVE") return ".wav";
@@ -868,7 +900,7 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
868
900
  timeout: 12e4,
869
901
  stdio: ["pipe", "pipe", "pipe"]
870
902
  });
871
- if (ffmpegResult.status === 0 && (0, import_node_fs25.existsSync)(outputPath)) {
903
+ if (ffmpegResult.status === 0 && (0, import_node_fs26.existsSync)(outputPath)) {
872
904
  logger.info(`[whisper-local] ffmpeg \u8F6C\u6362\u5B8C\u6210: ${outputPath}`);
873
905
  return { ok: true };
874
906
  }
@@ -881,7 +913,7 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
881
913
  ["--rate", "16000", "--mono", inputPath, outputPath],
882
914
  { encoding: "utf-8", timeout: 12e4, stdio: ["pipe", "pipe", "pipe"] }
883
915
  );
884
- if (opusResult.status === 0 && (0, import_node_fs25.existsSync)(outputPath)) {
916
+ if (opusResult.status === 0 && (0, import_node_fs26.existsSync)(outputPath)) {
885
917
  logger.info(`[whisper-local] opusdec \u8F6C\u6362\u5B8C\u6210: ${outputPath}`);
886
918
  return { ok: true };
887
919
  }
@@ -895,7 +927,7 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
895
927
  if (detectedExt && !inputPath.endsWith(detectedExt)) {
896
928
  tmpCopy = inputPath + ".detected" + detectedExt;
897
929
  try {
898
- (0, import_node_fs25.copyFileSync)(inputPath, tmpCopy);
930
+ (0, import_node_fs26.copyFileSync)(inputPath, tmpCopy);
899
931
  actualInputPath = tmpCopy;
900
932
  logger.info(
901
933
  `[whisper-local] \u68C0\u6D4B\u5230\u5B9E\u9645\u683C\u5F0F ${detectedExt}\uFF0C\u4E34\u65F6\u91CD\u547D\u540D`
@@ -919,22 +951,22 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
919
951
  timeout: 12e4,
920
952
  stdio: ["pipe", "pipe", "pipe"]
921
953
  });
922
- if (tmpCopy && (0, import_node_fs25.existsSync)(tmpCopy)) {
954
+ if (tmpCopy && (0, import_node_fs26.existsSync)(tmpCopy)) {
923
955
  try {
924
- (0, import_node_fs25.unlinkSync)(tmpCopy);
956
+ (0, import_node_fs26.unlinkSync)(tmpCopy);
925
957
  } catch {
926
958
  }
927
959
  }
928
- if (afResult.status === 0 && (0, import_node_fs25.existsSync)(outputPath)) {
960
+ if (afResult.status === 0 && (0, import_node_fs26.existsSync)(outputPath)) {
929
961
  logger.info(`[whisper-local] afconvert \u8F6C\u6362\u5B8C\u6210: ${outputPath}`);
930
962
  return { ok: true };
931
963
  }
932
964
  const stderr = afResult.stderr?.slice(0, 200) ?? "";
933
965
  return { ok: false, error: `afconvert \u8F6C\u6362\u5931\u8D25 (exit ${afResult.status}): ${stderr}` };
934
966
  } catch (err) {
935
- if (tmpCopy && (0, import_node_fs25.existsSync)(tmpCopy)) {
967
+ if (tmpCopy && (0, import_node_fs26.existsSync)(tmpCopy)) {
936
968
  try {
937
- (0, import_node_fs25.unlinkSync)(tmpCopy);
969
+ (0, import_node_fs26.unlinkSync)(tmpCopy);
938
970
  } catch {
939
971
  }
940
972
  }
@@ -945,9 +977,9 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
945
977
  return { ok: false, error: `\u65E0\u6CD5\u5C06\u97F3\u9891\u8F6C\u6362\u4E3A WAV \u683C\u5F0F\u3002${fmtHint}` };
946
978
  }
947
979
  function cleanupTmpWav(path2) {
948
- if (path2 && (0, import_node_fs25.existsSync)(path2)) {
980
+ if (path2 && (0, import_node_fs26.existsSync)(path2)) {
949
981
  try {
950
- (0, import_node_fs25.unlinkSync)(path2);
982
+ (0, import_node_fs26.unlinkSync)(path2);
951
983
  } catch {
952
984
  }
953
985
  }
@@ -1033,13 +1065,13 @@ function formatBytes2(bytes) {
1033
1065
  if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
1034
1066
  return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)}GB`;
1035
1067
  }
1036
- var import_node_child_process2, import_node_fs25, import_node_path21, import_promises3, import_node_stream2, import_node_os4, WHISPER_MODELS_DIR, WHISPER_BIN_DIR, HF_MODEL_URL_TEMPLATE, MODELSCOPE_MODEL_URL_TEMPLATE, PROBE_TIMEOUT_MS, MODEL_FILENAMES, MODEL_DISK_SIZES;
1068
+ var import_node_child_process2, import_node_fs26, import_node_path22, import_promises3, import_node_stream2, import_node_os4, WHISPER_MODELS_DIR, WHISPER_BIN_DIR, HF_MODEL_URL_TEMPLATE, MODELSCOPE_MODEL_URL_TEMPLATE, PROBE_TIMEOUT_MS, MODEL_FILENAMES, MODEL_DISK_SIZES;
1037
1069
  var init_whisper_local = __esm({
1038
1070
  "src/recording/whisper-local.ts"() {
1039
1071
  "use strict";
1040
1072
  import_node_child_process2 = require("child_process");
1041
- import_node_fs25 = require("fs");
1042
- import_node_path21 = require("path");
1073
+ import_node_fs26 = require("fs");
1074
+ import_node_path22 = require("path");
1043
1075
  import_promises3 = require("stream/promises");
1044
1076
  import_node_stream2 = require("stream");
1045
1077
  import_node_os4 = require("os");
@@ -1194,7 +1226,7 @@ async function initializeAsr(config, dataDir, logger) {
1194
1226
  }
1195
1227
  }
1196
1228
  async function transcribeAudio(audioFilePath, config, logger, options = {}) {
1197
- if (!(0, import_node_fs26.existsSync)(audioFilePath)) {
1229
+ if (!(0, import_node_fs27.existsSync)(audioFilePath)) {
1198
1230
  return { ok: false, error: `\u97F3\u9891\u6587\u4EF6\u4E0D\u5B58\u5728: ${audioFilePath}` };
1199
1231
  }
1200
1232
  logger.info(
@@ -1338,8 +1370,8 @@ async function runTranscriptionWorkflow(params) {
1338
1370
  createdAt
1339
1371
  );
1340
1372
  const transcriptDataFilename = buildTranscriptDataFilename(recordingId);
1341
- const transcriptDataPath = (0, import_node_path22.join)(transcriptDataDir, transcriptDataFilename);
1342
- (0, import_node_fs26.writeFileSync)(
1373
+ const transcriptDataPath = (0, import_node_path23.join)(transcriptDataDir, transcriptDataFilename);
1374
+ (0, import_node_fs27.writeFileSync)(
1343
1375
  transcriptDataPath,
1344
1376
  JSON.stringify(transcriptData, null, 2),
1345
1377
  "utf-8"
@@ -1347,14 +1379,14 @@ async function runTranscriptionWorkflow(params) {
1347
1379
  logger.info(`[asr] \u8F6C\u5199 JSON \u5DF2\u5199\u5165: ${transcriptDataPath}`);
1348
1380
  const safeSummary = title.replace(/[/\\:*?"<>|]/g, "").trim().slice(0, 20);
1349
1381
  const filename = safeSummary ? `${recordingId}_${safeSummary}.md` : `${recordingId}.md`;
1350
- const filePath = (0, import_node_path22.join)(transcriptsDir, filename);
1351
- (0, import_node_fs26.writeFileSync)(filePath, markdown, "utf-8");
1382
+ const filePath = (0, import_node_path23.join)(transcriptsDir, filename);
1383
+ (0, import_node_fs27.writeFileSync)(filePath, markdown, "utf-8");
1352
1384
  logger.info(`[asr] \u8F6C\u5199\u6587\u672C\u5DF2\u5199\u5165: ${filePath}`);
1353
1385
  let summaryFilename;
1354
1386
  if (summary) {
1355
1387
  summaryFilename = `${recordingId}.md`;
1356
- const summaryFilePath = (0, import_node_path22.join)(summariesDir, summaryFilename);
1357
- (0, import_node_fs26.writeFileSync)(summaryFilePath, summary, "utf-8");
1388
+ const summaryFilePath = (0, import_node_path23.join)(summariesDir, summaryFilename);
1389
+ (0, import_node_fs27.writeFileSync)(summaryFilePath, summary, "utf-8");
1358
1390
  logger.info(`[asr] \u6458\u8981\u6587\u672C\u5DF2\u5199\u5165: ${summaryFilePath}`);
1359
1391
  }
1360
1392
  return {
@@ -1439,7 +1471,7 @@ async function transcribeWithModelProxy(audioOssUrl, apiConfig, logger) {
1439
1471
  }
1440
1472
  async function transcribeWithWhisperLocal2(audioFilePath, config, logger) {
1441
1473
  const { transcribeWithWhisperLocal: runLocal } = await Promise.resolve().then(() => (init_whisper_local(), whisper_local_exports));
1442
- const dataDir = process.env.OPENCLAW_STATE_DIR ?? process.env.QCLAW_STATE_DIR ?? (0, import_node_path22.join)(audioFilePath, "..", "..", "..");
1474
+ const dataDir = process.env.OPENCLAW_STATE_DIR ?? process.env.QCLAW_STATE_DIR ?? (0, import_node_path23.join)(audioFilePath, "..", "..", "..");
1443
1475
  const localConfig = config.local ?? {};
1444
1476
  const result = await runLocal(
1445
1477
  audioFilePath,
@@ -1742,12 +1774,12 @@ function formatTranscriptSegmentText(segment) {
1742
1774
  }
1743
1775
  return text;
1744
1776
  }
1745
- var import_node_fs26, import_node_path22, DEFAULT_LONG_RECORDING_POLL_INTERVAL_MS, DEFAULT_LONG_RECORDING_MAX_POLL_ATTEMPTS, LONG_RECORDING_RUNNING_STATUSES, LONG_RECORDING_TERMINAL_FAILURE_STATUSES;
1777
+ var import_node_fs27, import_node_path23, DEFAULT_LONG_RECORDING_POLL_INTERVAL_MS, DEFAULT_LONG_RECORDING_MAX_POLL_ATTEMPTS, LONG_RECORDING_RUNNING_STATUSES, LONG_RECORDING_TERMINAL_FAILURE_STATUSES;
1746
1778
  var init_asr = __esm({
1747
1779
  "src/recording/asr.ts"() {
1748
1780
  "use strict";
1749
- import_node_fs26 = require("fs");
1750
- import_node_path22 = require("path");
1781
+ import_node_fs27 = require("fs");
1782
+ import_node_path23 = require("path");
1751
1783
  init_credentials();
1752
1784
  init_env();
1753
1785
  init_transcript_document();
@@ -5392,7 +5424,7 @@ function readBuildInjectedVersion() {
5392
5424
  if (false) {
5393
5425
  return void 0;
5394
5426
  }
5395
- const version = "1.10.3".trim();
5427
+ const version = "1.10.4".trim();
5396
5428
  return version || void 0;
5397
5429
  }
5398
5430
  function readPluginVersionFromPackageJson() {
@@ -7196,7 +7228,7 @@ function resolveUpdateChannel(params) {
7196
7228
  }
7197
7229
 
7198
7230
  // src/update/index.ts
7199
- var import_node_path9 = require("path");
7231
+ var import_node_path10 = require("path");
7200
7232
 
7201
7233
  // src/update/checker.ts
7202
7234
  function parseSemver(v) {
@@ -7298,8 +7330,8 @@ var UpdateChecker = class {
7298
7330
  };
7299
7331
 
7300
7332
  // src/update/executor.ts
7301
- var import_node_fs9 = require("fs");
7302
- var import_node_path8 = require("path");
7333
+ var import_node_fs10 = require("fs");
7334
+ var import_node_path9 = require("path");
7303
7335
  var import_node_os = require("os");
7304
7336
  var VERSION_PATTERN = /^\d+\.\d+\.\d+(-[\w.]+)?$/;
7305
7337
  var BASE_URL = "https://artifact.yoooclaw.com/plugin";
@@ -7309,9 +7341,9 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7309
7341
  }
7310
7342
  const tgzUrl = `${BASE_URL}/v${version}/yoooclaw-phone-notifications-${version}.tgz`;
7311
7343
  logger.info(`\u6267\u884C\u66F4\u65B0: ${tgzUrl} \u2192 ${targetDir}`);
7312
- const workDir = (0, import_node_fs9.mkdtempSync)((0, import_node_path8.join)((0, import_node_os.tmpdir)(), ".openclaw-plugin-update-"));
7313
- const tgzPath = (0, import_node_path8.join)(workDir, "plugin.tgz");
7314
- const stagingDir = (0, import_node_path8.join)(workDir, "staged");
7344
+ const workDir = (0, import_node_fs10.mkdtempSync)((0, import_node_path9.join)((0, import_node_os.tmpdir)(), ".openclaw-plugin-update-"));
7345
+ const tgzPath = (0, import_node_path9.join)(workDir, "plugin.tgz");
7346
+ const stagingDir = (0, import_node_path9.join)(workDir, "staged");
7315
7347
  let backupDir = null;
7316
7348
  try {
7317
7349
  logger.info("\u4E0B\u8F7D\u63D2\u4EF6\u5305...");
@@ -7320,9 +7352,9 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7320
7352
  return { success: false, message: `\u4E0B\u8F7D\u5931\u8D25 (HTTP ${response.status}): ${tgzUrl}` };
7321
7353
  }
7322
7354
  const buffer = Buffer.from(await response.arrayBuffer());
7323
- (0, import_node_fs9.writeFileSync)(tgzPath, buffer);
7355
+ (0, import_node_fs10.writeFileSync)(tgzPath, buffer);
7324
7356
  logger.info(`\u4E0B\u8F7D\u5B8C\u6210 (${buffer.length} bytes)`);
7325
- (0, import_node_fs9.mkdirSync)(stagingDir, { recursive: true });
7357
+ (0, import_node_fs10.mkdirSync)(stagingDir, { recursive: true });
7326
7358
  const tarResult = await runCommand(
7327
7359
  ["tar", "-xzf", tgzPath, "-C", stagingDir, "--strip-components=1"],
7328
7360
  { timeoutMs: 3e4 }
@@ -7331,14 +7363,14 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7331
7363
  const err = tarResult.stderr || tarResult.stdout || "unknown error";
7332
7364
  return { success: false, message: `\u89E3\u538B\u5931\u8D25: ${err}` };
7333
7365
  }
7334
- (0, import_node_fs9.mkdirSync)((0, import_node_path8.dirname)(targetDir), { recursive: true });
7366
+ (0, import_node_fs10.mkdirSync)((0, import_node_path9.dirname)(targetDir), { recursive: true });
7335
7367
  try {
7336
7368
  backupDir = `${targetDir}.bak.${Date.now()}`;
7337
- (0, import_node_fs9.renameSync)(targetDir, backupDir);
7369
+ (0, import_node_fs10.renameSync)(targetDir, backupDir);
7338
7370
  } catch {
7339
7371
  backupDir = null;
7340
7372
  }
7341
- (0, import_node_fs9.renameSync)(stagingDir, targetDir);
7373
+ (0, import_node_fs10.renameSync)(stagingDir, targetDir);
7342
7374
  try {
7343
7375
  await updateConfigRecord2(version, tgzUrl);
7344
7376
  } catch (err) {
@@ -7346,7 +7378,7 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7346
7378
  }
7347
7379
  if (backupDir) {
7348
7380
  try {
7349
- (0, import_node_fs9.rmSync)(backupDir, { force: true, recursive: true });
7381
+ (0, import_node_fs10.rmSync)(backupDir, { force: true, recursive: true });
7350
7382
  } catch {
7351
7383
  }
7352
7384
  }
@@ -7356,8 +7388,8 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7356
7388
  } catch (err) {
7357
7389
  if (backupDir) {
7358
7390
  try {
7359
- (0, import_node_fs9.rmSync)(targetDir, { force: true, recursive: true });
7360
- (0, import_node_fs9.renameSync)(backupDir, targetDir);
7391
+ (0, import_node_fs10.rmSync)(targetDir, { force: true, recursive: true });
7392
+ (0, import_node_fs10.renameSync)(backupDir, targetDir);
7361
7393
  logger.info("\u5DF2\u56DE\u6EDA\u5230\u4E4B\u524D\u7248\u672C");
7362
7394
  } catch (rollbackErr) {
7363
7395
  logger.error(`\u56DE\u6EDA\u5931\u8D25: ${String(rollbackErr)}`);
@@ -7368,7 +7400,7 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7368
7400
  return { success: false, message: errMsg };
7369
7401
  } finally {
7370
7402
  try {
7371
- (0, import_node_fs9.rmSync)(workDir, { force: true, recursive: true });
7403
+ (0, import_node_fs10.rmSync)(workDir, { force: true, recursive: true });
7372
7404
  } catch {
7373
7405
  }
7374
7406
  }
@@ -7383,7 +7415,7 @@ function resolveTargetDir(api) {
7383
7415
  if (installPath) return installPath;
7384
7416
  } catch {
7385
7417
  }
7386
- return (0, import_node_path9.join)(api.runtime.state.resolveStateDir(), "extensions", PLUGIN_ID);
7418
+ return (0, import_node_path10.join)(api.runtime.state.resolveStateDir(), "extensions", PLUGIN_ID);
7387
7419
  }
7388
7420
  async function updateConfigRecord(api, version, targetDir, tgzUrl) {
7389
7421
  const configApi = api.runtime.config;
@@ -7571,10 +7603,10 @@ function registerAutoUpdateLifecycle(deps) {
7571
7603
  }
7572
7604
 
7573
7605
  // src/plugin/cli.ts
7574
- var import_node_path17 = require("path");
7606
+ var import_node_path18 = require("path");
7575
7607
 
7576
7608
  // src/cli/auth.ts
7577
- var import_node_fs10 = require("fs");
7609
+ var import_node_fs11 = require("fs");
7578
7610
  init_credentials();
7579
7611
  function registerAuthCli(program) {
7580
7612
  const auth = program.command("auth").description("\u7528\u6237\u8BA4\u8BC1\u7BA1\u7406");
@@ -7610,12 +7642,12 @@ function registerAuthCli(program) {
7610
7642
  });
7611
7643
  auth.command("clear").description("\u6E05\u9664\u5DF2\u4FDD\u5B58\u7684\u8BA4\u8BC1\u4FE1\u606F").action(() => {
7612
7644
  const path2 = credentialsPath();
7613
- if ((0, import_node_fs10.existsSync)(path2)) {
7645
+ if ((0, import_node_fs11.existsSync)(path2)) {
7614
7646
  const creds = readCredentials();
7615
7647
  delete creds.apiKey;
7616
7648
  delete creds.token;
7617
7649
  if (Object.keys(creds).length === 0) {
7618
- (0, import_node_fs10.rmSync)(path2, { force: true });
7650
+ (0, import_node_fs11.rmSync)(path2, { force: true });
7619
7651
  } else {
7620
7652
  writeCredentials(creds);
7621
7653
  }
@@ -7747,23 +7779,23 @@ function registerNtfStats(ntf, ctx) {
7747
7779
  }
7748
7780
 
7749
7781
  // src/cli/ntf-sync.ts
7750
- var import_node_fs11 = require("fs");
7751
- var import_node_path10 = require("path");
7782
+ var import_node_fs12 = require("fs");
7783
+ var import_node_path11 = require("path");
7752
7784
  var SYNC_FETCH_LIMIT = 300;
7753
7785
  function checkpointPath(dir) {
7754
- return (0, import_node_path10.join)(dir, ".checkpoint.json");
7786
+ return (0, import_node_path11.join)(dir, ".checkpoint.json");
7755
7787
  }
7756
7788
  function readCheckpoint(dir) {
7757
7789
  const p = checkpointPath(dir);
7758
- if (!(0, import_node_fs11.existsSync)(p)) return {};
7790
+ if (!(0, import_node_fs12.existsSync)(p)) return {};
7759
7791
  try {
7760
- return JSON.parse((0, import_node_fs11.readFileSync)(p, "utf-8"));
7792
+ return JSON.parse((0, import_node_fs12.readFileSync)(p, "utf-8"));
7761
7793
  } catch {
7762
7794
  return {};
7763
7795
  }
7764
7796
  }
7765
7797
  function writeCheckpoint(dir, data) {
7766
- (0, import_node_fs11.writeFileSync)(checkpointPath(dir), JSON.stringify(data, null, 2), "utf-8");
7798
+ (0, import_node_fs12.writeFileSync)(checkpointPath(dir), JSON.stringify(data, null, 2), "utf-8");
7767
7799
  }
7768
7800
  function registerNtfSync(ntf, ctx) {
7769
7801
  const sync = ntf.command("sync").description("\u540C\u6B65\u901A\u77E5\u5230\u8BB0\u5FC6\u7CFB\u7EDF");
@@ -7856,24 +7888,24 @@ function registerNtfSync(ntf, ctx) {
7856
7888
  }
7857
7889
 
7858
7890
  // src/cli/ntf-monitor.ts
7859
- var import_node_fs12 = require("fs");
7860
- var import_node_path11 = require("path");
7891
+ var import_node_fs13 = require("fs");
7892
+ var import_node_path12 = require("path");
7861
7893
  function tasksDir2(ctx) {
7862
7894
  const base = ctx.workspaceDir || ctx.stateDir;
7863
7895
  if (!base) throw new Error("workspaceDir and stateDir both unavailable");
7864
- return (0, import_node_path11.join)(base, "tasks");
7896
+ return (0, import_node_path12.join)(base, "tasks");
7865
7897
  }
7866
7898
  function readMeta2(taskDir) {
7867
- const metaPath = (0, import_node_path11.join)(taskDir, "meta.json");
7868
- if (!(0, import_node_fs12.existsSync)(metaPath)) return null;
7899
+ const metaPath = (0, import_node_path12.join)(taskDir, "meta.json");
7900
+ if (!(0, import_node_fs13.existsSync)(metaPath)) return null;
7869
7901
  try {
7870
- return JSON.parse((0, import_node_fs12.readFileSync)(metaPath, "utf-8"));
7902
+ return JSON.parse((0, import_node_fs13.readFileSync)(metaPath, "utf-8"));
7871
7903
  } catch {
7872
7904
  return null;
7873
7905
  }
7874
7906
  }
7875
7907
  function writeMeta2(taskDir, meta) {
7876
- (0, import_node_fs12.writeFileSync)((0, import_node_path11.join)(taskDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8");
7908
+ (0, import_node_fs13.writeFileSync)((0, import_node_path12.join)(taskDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8");
7877
7909
  }
7878
7910
  function generateReadme(name, description) {
7879
7911
  return `# Monitor Task: ${name}
@@ -7892,27 +7924,27 @@ function registerNtfMonitor(ntf, ctx) {
7892
7924
  const monitor = ntf.command("monitor").description("\u901A\u77E5\u76D1\u63A7\u4EFB\u52A1\u7BA1\u7406");
7893
7925
  monitor.command("list").description("\u5217\u51FA\u6240\u6709\u76D1\u63A7\u4EFB\u52A1").action(() => {
7894
7926
  const dir = tasksDir2(ctx);
7895
- if (!(0, import_node_fs12.existsSync)(dir)) {
7927
+ if (!(0, import_node_fs13.existsSync)(dir)) {
7896
7928
  output({ ok: true, tasks: [] });
7897
7929
  return;
7898
7930
  }
7899
7931
  const tasks = [];
7900
- for (const entry of (0, import_node_fs12.readdirSync)(dir, { withFileTypes: true })) {
7932
+ for (const entry of (0, import_node_fs13.readdirSync)(dir, { withFileTypes: true })) {
7901
7933
  if (!entry.isDirectory()) continue;
7902
- const meta = readMeta2((0, import_node_path11.join)(dir, entry.name));
7934
+ const meta = readMeta2((0, import_node_path12.join)(dir, entry.name));
7903
7935
  if (meta) tasks.push(meta);
7904
7936
  }
7905
7937
  output({ ok: true, tasks });
7906
7938
  });
7907
7939
  monitor.command("show <name>").description("\u67E5\u770B\u76D1\u63A7\u4EFB\u52A1\u8BE6\u60C5").action((name) => {
7908
- const taskDir = (0, import_node_path11.join)(tasksDir2(ctx), name);
7940
+ const taskDir = (0, import_node_path12.join)(tasksDir2(ctx), name);
7909
7941
  const meta = readMeta2(taskDir);
7910
7942
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
7911
- const checkpointPath2 = (0, import_node_path11.join)(taskDir, "checkpoint.json");
7943
+ const checkpointPath2 = (0, import_node_path12.join)(taskDir, "checkpoint.json");
7912
7944
  let checkpoint = {};
7913
- if ((0, import_node_fs12.existsSync)(checkpointPath2)) {
7945
+ if ((0, import_node_fs13.existsSync)(checkpointPath2)) {
7914
7946
  try {
7915
- checkpoint = JSON.parse((0, import_node_fs12.readFileSync)(checkpointPath2, "utf-8"));
7947
+ checkpoint = JSON.parse((0, import_node_fs13.readFileSync)(checkpointPath2, "utf-8"));
7916
7948
  } catch {
7917
7949
  }
7918
7950
  }
@@ -7927,8 +7959,8 @@ function registerNtfMonitor(ntf, ctx) {
7927
7959
  monitor.command("create <name>").description("\u521B\u5EFA\u76D1\u63A7\u4EFB\u52A1").requiredOption("--description <text>", "\u4EFB\u52A1\u63CF\u8FF0").requiredOption("--match-rules <json>", "\u5339\u914D\u89C4\u5219 JSON").requiredOption("--schedule <cron>", "cron \u8868\u8FBE\u5F0F").action(
7928
7960
  (name, opts) => {
7929
7961
  const dir = tasksDir2(ctx);
7930
- const taskDir = (0, import_node_path11.join)(dir, name);
7931
- if ((0, import_node_fs12.existsSync)(taskDir)) {
7962
+ const taskDir = (0, import_node_path12.join)(dir, name);
7963
+ if ((0, import_node_fs13.existsSync)(taskDir)) {
7932
7964
  exitError("ALREADY_EXISTS", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u5DF2\u5B58\u5728`);
7933
7965
  }
7934
7966
  let matchRules;
@@ -7940,7 +7972,7 @@ function registerNtfMonitor(ntf, ctx) {
7940
7972
  "match-rules \u5FC5\u987B\u662F\u5408\u6CD5\u7684 JSON"
7941
7973
  );
7942
7974
  }
7943
- (0, import_node_fs12.mkdirSync)(taskDir, { recursive: true });
7975
+ (0, import_node_fs13.mkdirSync)(taskDir, { recursive: true });
7944
7976
  const meta = {
7945
7977
  name,
7946
7978
  description: opts.description,
@@ -7950,13 +7982,13 @@ function registerNtfMonitor(ntf, ctx) {
7950
7982
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
7951
7983
  };
7952
7984
  writeMeta2(taskDir, meta);
7953
- (0, import_node_fs12.writeFileSync)(
7954
- (0, import_node_path11.join)(taskDir, "fetch.py"),
7985
+ (0, import_node_fs13.writeFileSync)(
7986
+ (0, import_node_path12.join)(taskDir, "fetch.py"),
7955
7987
  generateFetchPy(name, matchRules),
7956
7988
  "utf-8"
7957
7989
  );
7958
- (0, import_node_fs12.writeFileSync)(
7959
- (0, import_node_path11.join)(taskDir, "README.md"),
7990
+ (0, import_node_fs13.writeFileSync)(
7991
+ (0, import_node_path12.join)(taskDir, "README.md"),
7960
7992
  generateReadme(name, opts.description),
7961
7993
  "utf-8"
7962
7994
  );
@@ -7984,8 +8016,8 @@ function registerNtfMonitor(ntf, ctx) {
7984
8016
  }
7985
8017
  );
7986
8018
  monitor.command("delete <name>").description("\u5220\u9664\u76D1\u63A7\u4EFB\u52A1").option("--yes", "\u8DF3\u8FC7\u786E\u8BA4").action((name, opts) => {
7987
- const taskDir = (0, import_node_path11.join)(tasksDir2(ctx), name);
7988
- if (!(0, import_node_fs12.existsSync)(taskDir)) {
8019
+ const taskDir = (0, import_node_path12.join)(tasksDir2(ctx), name);
8020
+ if (!(0, import_node_fs13.existsSync)(taskDir)) {
7989
8021
  exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
7990
8022
  }
7991
8023
  if (!opts.yes) {
@@ -7998,7 +8030,7 @@ function registerNtfMonitor(ntf, ctx) {
7998
8030
  });
7999
8031
  process.exit(1);
8000
8032
  }
8001
- (0, import_node_fs12.rmSync)(taskDir, { recursive: true, force: true });
8033
+ (0, import_node_fs13.rmSync)(taskDir, { recursive: true, force: true });
8002
8034
  output({
8003
8035
  ok: true,
8004
8036
  name,
@@ -8010,7 +8042,7 @@ function registerNtfMonitor(ntf, ctx) {
8010
8042
  });
8011
8043
  });
8012
8044
  monitor.command("enable <name>").description("\u542F\u7528\u76D1\u63A7\u4EFB\u52A1").action((name) => {
8013
- const taskDir = (0, import_node_path11.join)(tasksDir2(ctx), name);
8045
+ const taskDir = (0, import_node_path12.join)(tasksDir2(ctx), name);
8014
8046
  const meta = readMeta2(taskDir);
8015
8047
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
8016
8048
  meta.enabled = true;
@@ -8018,7 +8050,7 @@ function registerNtfMonitor(ntf, ctx) {
8018
8050
  output({ ok: true, name, enabled: true });
8019
8051
  });
8020
8052
  monitor.command("disable <name>").description("\u6682\u505C\u76D1\u63A7\u4EFB\u52A1").action((name) => {
8021
- const taskDir = (0, import_node_path11.join)(tasksDir2(ctx), name);
8053
+ const taskDir = (0, import_node_path12.join)(tasksDir2(ctx), name);
8022
8054
  const meta = readMeta2(taskDir);
8023
8055
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
8024
8056
  meta.enabled = false;
@@ -8327,9 +8359,9 @@ function registerLightSend(light) {
8327
8359
  }
8328
8360
 
8329
8361
  // src/cli/light-setup-tools.ts
8330
- var import_node_fs13 = require("fs");
8362
+ var import_node_fs14 = require("fs");
8331
8363
  var import_node_os2 = require("os");
8332
- var import_node_path12 = require("path");
8364
+ var import_node_path13 = require("path");
8333
8365
  function isObject(value) {
8334
8366
  return !!value && typeof value === "object" && !Array.isArray(value);
8335
8367
  }
@@ -8343,7 +8375,7 @@ function ensureArray(obj, key) {
8343
8375
  function resolveConfigPath2() {
8344
8376
  const fromEnv = process.env.OPENCLAW_CONFIG_PATH?.trim();
8345
8377
  if (fromEnv) return fromEnv;
8346
- return (0, import_node_path12.join)((0, import_node_os2.homedir)(), ".openclaw", "openclaw.json");
8378
+ return (0, import_node_path13.join)((0, import_node_os2.homedir)(), ".openclaw", "openclaw.json");
8347
8379
  }
8348
8380
  function upsertLightControlAlsoAllow(cfg) {
8349
8381
  if (!isObject(cfg.tools)) cfg.tools = {};
@@ -8372,12 +8404,12 @@ function upsertLightControlAlsoAllow(cfg) {
8372
8404
  function registerLightSetupTools(light) {
8373
8405
  light.command("setup").description("\u81EA\u52A8\u653E\u884C light_control\uFF08\u5199\u5165 tools.alsoAllow \u4E0E agents.main.tools.alsoAllow\uFF09").action(() => {
8374
8406
  const configPath = resolveConfigPath2();
8375
- if (!(0, import_node_fs13.existsSync)(configPath)) {
8407
+ if (!(0, import_node_fs14.existsSync)(configPath)) {
8376
8408
  exitError("CONFIG_NOT_FOUND", `\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6: ${configPath}`);
8377
8409
  }
8378
8410
  let cfg = {};
8379
8411
  try {
8380
- const raw = (0, import_node_fs13.readFileSync)(configPath, "utf-8");
8412
+ const raw = (0, import_node_fs14.readFileSync)(configPath, "utf-8");
8381
8413
  const parsed = JSON.parse(raw);
8382
8414
  if (isObject(parsed)) cfg = parsed;
8383
8415
  } catch (err) {
@@ -8385,8 +8417,8 @@ function registerLightSetupTools(light) {
8385
8417
  }
8386
8418
  const result = upsertLightControlAlsoAllow(cfg);
8387
8419
  try {
8388
- (0, import_node_fs13.mkdirSync)((0, import_node_path12.dirname)(configPath), { recursive: true });
8389
- (0, import_node_fs13.writeFileSync)(configPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
8420
+ (0, import_node_fs14.mkdirSync)((0, import_node_path13.dirname)(configPath), { recursive: true });
8421
+ (0, import_node_fs14.writeFileSync)(configPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
8390
8422
  } catch (err) {
8391
8423
  exitError("WRITE_FAILED", `\u5199\u5165\u914D\u7F6E\u5931\u8D25: ${err?.message ?? String(err)}`);
8392
8424
  }
@@ -8404,17 +8436,17 @@ function registerLightSetupTools(light) {
8404
8436
  }
8405
8437
 
8406
8438
  // src/cli/tunnel-status.ts
8407
- var import_node_fs14 = require("fs");
8408
- var import_node_path13 = require("path");
8439
+ var import_node_fs15 = require("fs");
8440
+ var import_node_path14 = require("path");
8409
8441
  init_credentials();
8410
8442
  init_env();
8411
- var STATUS_REL_PATH = (0, import_node_path13.join)("plugins", "phone-notifications", "tunnel-status.json");
8443
+ var STATUS_REL_PATH = (0, import_node_path14.join)("plugins", "phone-notifications", "tunnel-status.json");
8412
8444
  function readTunnelStatus(ctx) {
8413
8445
  if (!ctx.stateDir) return null;
8414
- const filePath = (0, import_node_path13.join)(ctx.stateDir, STATUS_REL_PATH);
8415
- if (!(0, import_node_fs14.existsSync)(filePath)) return null;
8446
+ const filePath = (0, import_node_path14.join)(ctx.stateDir, STATUS_REL_PATH);
8447
+ if (!(0, import_node_fs15.existsSync)(filePath)) return null;
8416
8448
  try {
8417
- return JSON.parse((0, import_node_fs14.readFileSync)(filePath, "utf-8"));
8449
+ return JSON.parse((0, import_node_fs15.readFileSync)(filePath, "utf-8"));
8418
8450
  } catch {
8419
8451
  return null;
8420
8452
  }
@@ -8482,24 +8514,24 @@ function registerNtfStoragePath(ntf, ctx) {
8482
8514
  }
8483
8515
 
8484
8516
  // src/cli/log-search.ts
8485
- var import_node_fs15 = require("fs");
8486
- var import_node_path14 = require("path");
8517
+ var import_node_fs16 = require("fs");
8518
+ var import_node_path15 = require("path");
8487
8519
  function resolveLogsDir(ctx) {
8488
8520
  if (ctx.stateDir) {
8489
- const dir = (0, import_node_path14.join)(
8521
+ const dir = (0, import_node_path15.join)(
8490
8522
  ctx.stateDir,
8491
8523
  "plugins",
8492
8524
  "phone-notifications",
8493
8525
  "logs"
8494
8526
  );
8495
- if ((0, import_node_fs15.existsSync)(dir)) return dir;
8527
+ if ((0, import_node_fs16.existsSync)(dir)) return dir;
8496
8528
  }
8497
8529
  return null;
8498
8530
  }
8499
8531
  function listLogDateKeys(dir) {
8500
8532
  const pattern = /^(\d{4}-\d{2}-\d{2})\.log$/;
8501
8533
  const keys = [];
8502
- for (const entry of (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true })) {
8534
+ for (const entry of (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true })) {
8503
8535
  if (!entry.isFile()) continue;
8504
8536
  const m = pattern.exec(entry.name);
8505
8537
  if (m) keys.push(m[1]);
@@ -8507,9 +8539,9 @@ function listLogDateKeys(dir) {
8507
8539
  return keys.sort().reverse();
8508
8540
  }
8509
8541
  function collectLogLines(dir, dateKey, keyword, limit, collected) {
8510
- const filePath = (0, import_node_path14.join)(dir, `${dateKey}.log`);
8511
- if (!(0, import_node_fs15.existsSync)(filePath)) return;
8512
- const content = (0, import_node_fs15.readFileSync)(filePath, "utf-8");
8542
+ const filePath = (0, import_node_path15.join)(dir, `${dateKey}.log`);
8543
+ if (!(0, import_node_fs16.existsSync)(filePath)) return;
8544
+ const content = (0, import_node_fs16.readFileSync)(filePath, "utf-8");
8513
8545
  const lowerKeyword = keyword?.toLowerCase();
8514
8546
  for (const line of content.split("\n")) {
8515
8547
  if (collected.length >= limit) return;
@@ -8576,12 +8608,12 @@ function registerEnvCli(ntf) {
8576
8608
  }
8577
8609
 
8578
8610
  // src/cli/doctor.ts
8579
- var import_node_fs19 = require("fs");
8611
+ var import_node_fs20 = require("fs");
8580
8612
  var import_node_readline = require("readline");
8581
8613
  init_host();
8582
8614
 
8583
8615
  // src/cli/doctor/check-dangerous-flags.ts
8584
- var import_node_fs16 = require("fs");
8616
+ var import_node_fs17 = require("fs");
8585
8617
  function isObject2(v) {
8586
8618
  return !!v && typeof v === "object" && !Array.isArray(v);
8587
8619
  }
@@ -8598,13 +8630,13 @@ var checkDangerousFlags = ({ cfg, configPath }) => {
8598
8630
  detail: "\u8FD9\u4F1A\u5173\u95ED Control UI \u7684\u8BBE\u5907\u8EAB\u4EFD\u9A8C\u8BC1\uFF0C\u4EFB\u4F55\u4EBA\u90FD\u53EF\u4EE5\u8BBF\u95EE\u63A7\u5236\u9762\u677F\u3002",
8599
8631
  fixDescription: "\u8BBE\u4E3A false",
8600
8632
  fix: () => {
8601
- const raw = (0, import_node_fs16.readFileSync)(configPath, "utf-8");
8633
+ const raw = (0, import_node_fs17.readFileSync)(configPath, "utf-8");
8602
8634
  const config = JSON.parse(raw);
8603
8635
  const gw = config.gateway;
8604
8636
  const cui = gw.controlUi;
8605
8637
  cui.dangerouslyDisableDeviceAuth = false;
8606
- (0, import_node_fs16.copyFileSync)(configPath, configPath + ".bak");
8607
- (0, import_node_fs16.writeFileSync)(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
8638
+ (0, import_node_fs17.copyFileSync)(configPath, configPath + ".bak");
8639
+ (0, import_node_fs17.writeFileSync)(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
8608
8640
  }
8609
8641
  };
8610
8642
  };
@@ -8652,11 +8684,11 @@ function warnEmpty() {
8652
8684
  }
8653
8685
 
8654
8686
  // src/cli/doctor/check-state-dir-perms.ts
8655
- var import_node_fs17 = require("fs");
8687
+ var import_node_fs18 = require("fs");
8656
8688
  var checkStateDirPerms = ({ stateDir }) => {
8657
8689
  let mode;
8658
8690
  try {
8659
- mode = (0, import_node_fs17.statSync)(stateDir).mode;
8691
+ mode = (0, import_node_fs18.statSync)(stateDir).mode;
8660
8692
  } catch {
8661
8693
  return null;
8662
8694
  }
@@ -8670,7 +8702,7 @@ var checkStateDirPerms = ({ stateDir }) => {
8670
8702
  detail: "\u5176\u4ED6\u7528\u6237\u53EF\u4EE5\u8BFB\u53D6\u8BE5\u76EE\u5F55\u4E0B\u7684\u51ED\u8BC1\u548C\u914D\u7F6E\u6587\u4EF6\u3002",
8671
8703
  fixDescription: "chmod 700 " + stateDir,
8672
8704
  fix: () => {
8673
- (0, import_node_fs17.chmodSync)(stateDir, 448);
8705
+ (0, import_node_fs18.chmodSync)(stateDir, 448);
8674
8706
  }
8675
8707
  };
8676
8708
  };
@@ -8725,16 +8757,16 @@ var checkCredentials = () => {
8725
8757
  };
8726
8758
 
8727
8759
  // src/cli/doctor/check-tunnel.ts
8728
- var import_node_fs18 = require("fs");
8729
- var import_node_path15 = require("path");
8730
- var STATUS_REL_PATH2 = (0, import_node_path15.join)(
8760
+ var import_node_fs19 = require("fs");
8761
+ var import_node_path16 = require("path");
8762
+ var STATUS_REL_PATH2 = (0, import_node_path16.join)(
8731
8763
  "plugins",
8732
8764
  "phone-notifications",
8733
8765
  "tunnel-status.json"
8734
8766
  );
8735
8767
  var checkTunnel = ({ stateDir }) => {
8736
- const filePath = (0, import_node_path15.join)(stateDir, STATUS_REL_PATH2);
8737
- if (!(0, import_node_fs18.existsSync)(filePath)) {
8768
+ const filePath = (0, import_node_path16.join)(stateDir, STATUS_REL_PATH2);
8769
+ if (!(0, import_node_fs19.existsSync)(filePath)) {
8738
8770
  return {
8739
8771
  id: "tunnel",
8740
8772
  severity: "warn",
@@ -8746,7 +8778,7 @@ var checkTunnel = ({ stateDir }) => {
8746
8778
  }
8747
8779
  let status;
8748
8780
  try {
8749
- status = JSON.parse((0, import_node_fs18.readFileSync)(filePath, "utf-8"));
8781
+ status = JSON.parse((0, import_node_fs19.readFileSync)(filePath, "utf-8"));
8750
8782
  } catch {
8751
8783
  return {
8752
8784
  id: "tunnel",
@@ -8839,9 +8871,9 @@ function isObject5(v) {
8839
8871
  return !!v && typeof v === "object" && !Array.isArray(v);
8840
8872
  }
8841
8873
  function readConfig(configPath) {
8842
- if (!(0, import_node_fs19.existsSync)(configPath)) return {};
8874
+ if (!(0, import_node_fs20.existsSync)(configPath)) return {};
8843
8875
  try {
8844
- const parsed = JSON.parse((0, import_node_fs19.readFileSync)(configPath, "utf-8"));
8876
+ const parsed = JSON.parse((0, import_node_fs20.readFileSync)(configPath, "utf-8"));
8845
8877
  return isObject5(parsed) ? parsed : {};
8846
8878
  } catch {
8847
8879
  return {};
@@ -9042,7 +9074,7 @@ function registerRecStoragePath(rec, ctx) {
9042
9074
 
9043
9075
  // src/cli/rec-setup.ts
9044
9076
  var import_node_readline2 = require("readline");
9045
- var import_node_fs20 = require("fs");
9077
+ var import_node_fs21 = require("fs");
9046
9078
  function ask(rl, question) {
9047
9079
  return new Promise((resolve) => rl.question(question, resolve));
9048
9080
  }
@@ -9128,9 +9160,9 @@ async function setupLocal(rl) {
9128
9160
  function registerRecSetup(rec, ctx) {
9129
9161
  rec.command("setup").description("\u4EA4\u4E92\u5F0F\u914D\u7F6E ASR \u8F6C\u5199\u53C2\u6570\uFF0C\u4FDD\u5B58\u5230\u672C\u5730\u914D\u7F6E\u6587\u4EF6").action(async () => {
9130
9162
  const configPath = resolveAsrConfigPath(ctx);
9131
- if ((0, import_node_fs20.existsSync)(configPath)) {
9163
+ if ((0, import_node_fs21.existsSync)(configPath)) {
9132
9164
  try {
9133
- const existing = JSON.parse((0, import_node_fs20.readFileSync)(configPath, "utf-8"));
9165
+ const existing = JSON.parse((0, import_node_fs21.readFileSync)(configPath, "utf-8"));
9134
9166
  process.stderr.write(`\u5F53\u524D\u5DF2\u6709\u914D\u7F6E\uFF1Amode = ${existing.mode}`);
9135
9167
  if (existing.updatedAt) process.stderr.write(`\uFF0C\u66F4\u65B0\u4E8E ${existing.updatedAt}`);
9136
9168
  process.stderr.write("\n");
@@ -9143,7 +9175,7 @@ function registerRecSetup(rec, ctx) {
9143
9175
  const modeIdx = await askChoice(rl, "\u9009\u62E9\u6A21\u5F0F", ["api\uFF08\u4E91\u7AEF model-proxy \u957F\u5F55\u97F3\uFF09", "local\uFF08\u672C\u5730 Whisper\uFF09"]);
9144
9176
  const config = modeIdx === 0 ? await setupApi(rl) : await setupLocal(rl);
9145
9177
  const stored = { ...config, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
9146
- (0, import_node_fs20.writeFileSync)(configPath, JSON.stringify(stored, null, 2), "utf-8");
9178
+ (0, import_node_fs21.writeFileSync)(configPath, JSON.stringify(stored, null, 2), "utf-8");
9147
9179
  process.stderr.write(`
9148
9180
  \u2713 \u914D\u7F6E\u5DF2\u4FDD\u5B58\u5230 ${configPath}
9149
9181
 
@@ -9157,8 +9189,8 @@ function registerRecSetup(rec, ctx) {
9157
9189
 
9158
9190
  // src/cli/update.ts
9159
9191
  var import_node_child_process = require("child_process");
9160
- var import_node_fs21 = require("fs");
9161
- var import_node_path16 = require("path");
9192
+ var import_node_fs22 = require("fs");
9193
+ var import_node_path17 = require("path");
9162
9194
  var import_node_os3 = __toESM(require("os"), 1);
9163
9195
  init_host();
9164
9196
  var BASE_URL2 = "https://artifact.yoooclaw.com/plugin";
@@ -9217,9 +9249,9 @@ async function runUpdate(ctx, opts) {
9217
9249
  `);
9218
9250
  process.exit(1);
9219
9251
  }
9220
- const tmpScript = (0, import_node_path16.join)(import_node_os3.default.tmpdir(), `openclaw-install-${Date.now()}.mjs`);
9252
+ const tmpScript = (0, import_node_path17.join)(import_node_os3.default.tmpdir(), `openclaw-install-${Date.now()}.mjs`);
9221
9253
  try {
9222
- (0, import_node_fs21.writeFileSync)(tmpScript, installScript, "utf-8");
9254
+ (0, import_node_fs22.writeFileSync)(tmpScript, installScript, "utf-8");
9223
9255
  } catch (err) {
9224
9256
  const msg = `\u5199\u5165\u4E34\u65F6\u6587\u4EF6\u5931\u8D25: ${err?.message ?? String(err)}`;
9225
9257
  if (json) {
@@ -9237,7 +9269,7 @@ async function runUpdate(ctx, opts) {
9237
9269
  { stdio: "inherit" }
9238
9270
  );
9239
9271
  try {
9240
- (0, import_node_fs21.unlinkSync)(tmpScript);
9272
+ (0, import_node_fs22.unlinkSync)(tmpScript);
9241
9273
  } catch {
9242
9274
  }
9243
9275
  if (result.error) {
@@ -9301,10 +9333,10 @@ function inferOpenClawRootDir(workspaceDir) {
9301
9333
  if (!workspaceDir) {
9302
9334
  return void 0;
9303
9335
  }
9304
- if ((0, import_node_path17.basename)(workspaceDir) !== "workspace") {
9336
+ if ((0, import_node_path18.basename)(workspaceDir) !== "workspace") {
9305
9337
  return void 0;
9306
9338
  }
9307
- return (0, import_node_path17.dirname)(workspaceDir);
9339
+ return (0, import_node_path18.dirname)(workspaceDir);
9308
9340
  }
9309
9341
  function registerPluginCli(api, params) {
9310
9342
  const { logger, openclawDir } = params;
@@ -9550,12 +9582,12 @@ function registerLightControlTool(api, logger) {
9550
9582
  }
9551
9583
 
9552
9584
  // src/plugin/lifecycle.ts
9553
- var import_node_fs30 = require("fs");
9585
+ var import_node_fs31 = require("fs");
9554
9586
  init_host();
9555
9587
 
9556
9588
  // src/notification/app-name-map.ts
9557
- var import_node_fs22 = require("fs");
9558
- var import_node_path18 = require("path");
9589
+ var import_node_fs23 = require("fs");
9590
+ var import_node_path19 = require("path");
9559
9591
  init_credentials();
9560
9592
  init_env();
9561
9593
  var PLUGIN_STATE_DIR = "phone-notifications";
@@ -9576,7 +9608,7 @@ function isAppNameMapApiResponse(v) {
9576
9608
  );
9577
9609
  }
9578
9610
  function getCachePath(stateDir) {
9579
- return (0, import_node_path18.join)(stateDir, "plugins", PLUGIN_STATE_DIR, CACHE_FILE);
9611
+ return (0, import_node_path19.join)(stateDir, "plugins", PLUGIN_STATE_DIR, CACHE_FILE);
9580
9612
  }
9581
9613
  function createAppNameMapProvider(opts) {
9582
9614
  const { stateDir, logger } = opts;
@@ -9588,9 +9620,9 @@ function createAppNameMapProvider(opts) {
9588
9620
  let inFlightFetch = null;
9589
9621
  function loadFromDisk() {
9590
9622
  const path2 = getCachePath(stateDir);
9591
- if (!(0, import_node_fs22.existsSync)(path2)) return;
9623
+ if (!(0, import_node_fs23.existsSync)(path2)) return;
9592
9624
  try {
9593
- const raw = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf-8"));
9625
+ const raw = JSON.parse((0, import_node_fs23.readFileSync)(path2, "utf-8"));
9594
9626
  if (!isRecordOfStrings(raw)) return;
9595
9627
  map.clear();
9596
9628
  for (const [k, v] of Object.entries(raw)) map.set(k, v);
@@ -9634,10 +9666,10 @@ function createAppNameMapProvider(opts) {
9634
9666
  logger.warn("[app-name-map] refresh succeeded but got 0 entries");
9635
9667
  return;
9636
9668
  }
9637
- const dir = (0, import_node_path18.join)(stateDir, "plugins", PLUGIN_STATE_DIR);
9638
- (0, import_node_fs22.mkdirSync)(dir, { recursive: true });
9669
+ const dir = (0, import_node_path19.join)(stateDir, "plugins", PLUGIN_STATE_DIR);
9670
+ (0, import_node_fs23.mkdirSync)(dir, { recursive: true });
9639
9671
  const cachePath = getCachePath(stateDir);
9640
- (0, import_node_fs22.writeFileSync)(cachePath, JSON.stringify(Object.fromEntries(map), null, 2), "utf-8");
9672
+ (0, import_node_fs23.writeFileSync)(cachePath, JSON.stringify(Object.fromEntries(map), null, 2), "utf-8");
9641
9673
  logger.info(`[app-name-map] refreshed ${map.size} entries from server and saved: ${cachePath}`);
9642
9674
  } catch (e) {
9643
9675
  const message = e instanceof Error ? e.message : String(e);
@@ -9681,8 +9713,8 @@ function createAppNameMapProvider(opts) {
9681
9713
  }
9682
9714
 
9683
9715
  // src/recording/storage.ts
9684
- var import_node_fs23 = require("fs");
9685
- var import_node_path19 = require("path");
9716
+ var import_node_fs24 = require("fs");
9717
+ var import_node_path20 = require("path");
9686
9718
 
9687
9719
  // src/recording/state-machine.ts
9688
9720
  var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
@@ -9743,7 +9775,7 @@ function stripMarkdownFence(markdown) {
9743
9775
  }
9744
9776
  function deriveTitleFromTranscriptPath(transcriptFile, recordingId) {
9745
9777
  if (!transcriptFile) return void 0;
9746
- const name = (0, import_node_path19.basename)(transcriptFile, ".md");
9778
+ const name = (0, import_node_path20.basename)(transcriptFile, ".md");
9747
9779
  const prefix = `${recordingId}_`;
9748
9780
  if (name.startsWith(prefix)) {
9749
9781
  const derived = name.slice(prefix.length).trim();
@@ -9771,22 +9803,22 @@ function extractTranscriptContent(markdown) {
9771
9803
  return lines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
9772
9804
  }
9773
9805
  function resolveRecordingStorageDir(ctx, logger) {
9774
- const stateRecDir = (0, import_node_path19.join)(
9806
+ const stateRecDir = (0, import_node_path20.join)(
9775
9807
  ctx.stateDir,
9776
9808
  "plugins",
9777
9809
  "phone-notifications",
9778
9810
  RECORDINGS_DIR
9779
9811
  );
9780
9812
  try {
9781
- (0, import_node_fs23.mkdirSync)(stateRecDir, { recursive: true });
9813
+ (0, import_node_fs24.mkdirSync)(stateRecDir, { recursive: true });
9782
9814
  logger.info(`\u5F55\u97F3\u5C06\u5199\u5165 stateDir \u8DEF\u5F84: ${stateRecDir}`);
9783
9815
  return stateRecDir;
9784
9816
  } catch {
9785
9817
  }
9786
9818
  if (ctx.workspaceDir) {
9787
- const wsRecDir = (0, import_node_path19.join)(ctx.workspaceDir, RECORDINGS_DIR);
9819
+ const wsRecDir = (0, import_node_path20.join)(ctx.workspaceDir, RECORDINGS_DIR);
9788
9820
  try {
9789
- (0, import_node_fs23.mkdirSync)(wsRecDir, { recursive: true });
9821
+ (0, import_node_fs24.mkdirSync)(wsRecDir, { recursive: true });
9790
9822
  logger.warn(`stateDir \u4E0D\u53EF\u7528\uFF0C\u5F55\u97F3\u5DF2\u56DE\u9000\u5230 workspace \u8DEF\u5F84: ${wsRecDir}`);
9791
9823
  return wsRecDir;
9792
9824
  } catch {
@@ -9798,11 +9830,11 @@ var RecordingStorage = class {
9798
9830
  constructor(dir, logger) {
9799
9831
  this.logger = logger;
9800
9832
  this.dir = dir;
9801
- this.audioDir = (0, import_node_path19.join)(dir, AUDIO_DIR);
9802
- this.transcriptDataDir = (0, import_node_path19.join)(dir, TRANSCRIPT_DATA_DIR);
9803
- this.transcriptsDir = (0, import_node_path19.join)(dir, TRANSCRIPTS_DIR);
9804
- this.summariesDir = (0, import_node_path19.join)(dir, SUMMARIES_DIR);
9805
- this.indexPath = (0, import_node_path19.join)(dir, INDEX_FILE);
9833
+ this.audioDir = (0, import_node_path20.join)(dir, AUDIO_DIR);
9834
+ this.transcriptDataDir = (0, import_node_path20.join)(dir, TRANSCRIPT_DATA_DIR);
9835
+ this.transcriptsDir = (0, import_node_path20.join)(dir, TRANSCRIPTS_DIR);
9836
+ this.summariesDir = (0, import_node_path20.join)(dir, SUMMARIES_DIR);
9837
+ this.indexPath = (0, import_node_path20.join)(dir, INDEX_FILE);
9806
9838
  }
9807
9839
  dir;
9808
9840
  audioDir;
@@ -9813,10 +9845,10 @@ var RecordingStorage = class {
9813
9845
  index = { recordings: [] };
9814
9846
  /** 初始化目录结构并加载索引 */
9815
9847
  async init() {
9816
- (0, import_node_fs23.mkdirSync)(this.audioDir, { recursive: true });
9817
- (0, import_node_fs23.mkdirSync)(this.transcriptDataDir, { recursive: true });
9818
- (0, import_node_fs23.mkdirSync)(this.transcriptsDir, { recursive: true });
9819
- (0, import_node_fs23.mkdirSync)(this.summariesDir, { recursive: true });
9848
+ (0, import_node_fs24.mkdirSync)(this.audioDir, { recursive: true });
9849
+ (0, import_node_fs24.mkdirSync)(this.transcriptDataDir, { recursive: true });
9850
+ (0, import_node_fs24.mkdirSync)(this.transcriptsDir, { recursive: true });
9851
+ (0, import_node_fs24.mkdirSync)(this.summariesDir, { recursive: true });
9820
9852
  this.loadIndex();
9821
9853
  this.logger.info(
9822
9854
  `\u5F55\u97F3\u5B58\u50A8\u5DF2\u521D\u59CB\u5316: ${this.dir}\uFF08\u5171 ${this.index.recordings.length} \u6761\u8BB0\u5F55\uFF09`
@@ -9860,13 +9892,13 @@ var RecordingStorage = class {
9860
9892
  return id;
9861
9893
  }
9862
9894
  if (existing.transcriptDataFile) {
9863
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, existing.transcriptDataFile), { force: true });
9895
+ (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, existing.transcriptDataFile), { force: true });
9864
9896
  }
9865
9897
  if (existing.transcriptFile) {
9866
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, existing.transcriptFile), { force: true });
9898
+ (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, existing.transcriptFile), { force: true });
9867
9899
  }
9868
9900
  if (existing.summaryFile) {
9869
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, existing.summaryFile), { force: true });
9901
+ (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, existing.summaryFile), { force: true });
9870
9902
  }
9871
9903
  existing.metadata = metadata;
9872
9904
  existing.status = "syncing_openclaw";
@@ -9934,7 +9966,7 @@ var RecordingStorage = class {
9934
9966
  if (!entry) return;
9935
9967
  const nextTranscriptDataFile = `${TRANSCRIPT_DATA_DIR}/${filename}`;
9936
9968
  if (entry.transcriptDataFile && entry.transcriptDataFile !== nextTranscriptDataFile) {
9937
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, entry.transcriptDataFile), { force: true });
9969
+ (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, entry.transcriptDataFile), { force: true });
9938
9970
  }
9939
9971
  entry.transcriptDataFile = nextTranscriptDataFile;
9940
9972
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -9948,7 +9980,7 @@ var RecordingStorage = class {
9948
9980
  if (!entry) return;
9949
9981
  const nextTranscriptFile = `${TRANSCRIPTS_DIR}/${filename}`;
9950
9982
  if (entry.transcriptFile && entry.transcriptFile !== nextTranscriptFile) {
9951
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, entry.transcriptFile), { force: true });
9983
+ (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, entry.transcriptFile), { force: true });
9952
9984
  }
9953
9985
  entry.transcriptFile = nextTranscriptFile;
9954
9986
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -9962,7 +9994,7 @@ var RecordingStorage = class {
9962
9994
  if (!entry) return;
9963
9995
  const nextSummaryFile = `${SUMMARIES_DIR}/${filename}`;
9964
9996
  if (entry.summaryFile && entry.summaryFile !== nextSummaryFile) {
9965
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, entry.summaryFile), { force: true });
9997
+ (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, entry.summaryFile), { force: true });
9966
9998
  }
9967
9999
  entry.summaryFile = nextSummaryFile;
9968
10000
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -10060,24 +10092,24 @@ var RecordingStorage = class {
10060
10092
  const entry = this.findById(recordingId);
10061
10093
  if (!entry) return false;
10062
10094
  if (entry.audioFile) {
10063
- const audioPath = (0, import_node_path19.join)(this.dir, entry.audioFile);
10064
- (0, import_node_fs23.rmSync)(audioPath, { force: true });
10095
+ const audioPath = (0, import_node_path20.join)(this.dir, entry.audioFile);
10096
+ (0, import_node_fs24.rmSync)(audioPath, { force: true });
10065
10097
  }
10066
10098
  if (entry.srtFile) {
10067
- const srtPath = (0, import_node_path19.join)(this.dir, entry.srtFile);
10068
- (0, import_node_fs23.rmSync)(srtPath, { force: true });
10099
+ const srtPath = (0, import_node_path20.join)(this.dir, entry.srtFile);
10100
+ (0, import_node_fs24.rmSync)(srtPath, { force: true });
10069
10101
  }
10070
10102
  if (entry.transcriptDataFile) {
10071
- const transcriptDataPath = (0, import_node_path19.join)(this.dir, entry.transcriptDataFile);
10072
- (0, import_node_fs23.rmSync)(transcriptDataPath, { force: true });
10103
+ const transcriptDataPath = (0, import_node_path20.join)(this.dir, entry.transcriptDataFile);
10104
+ (0, import_node_fs24.rmSync)(transcriptDataPath, { force: true });
10073
10105
  }
10074
10106
  if (entry.transcriptFile) {
10075
- const transcriptPath = (0, import_node_path19.join)(this.dir, entry.transcriptFile);
10076
- (0, import_node_fs23.rmSync)(transcriptPath, { force: true });
10107
+ const transcriptPath = (0, import_node_path20.join)(this.dir, entry.transcriptFile);
10108
+ (0, import_node_fs24.rmSync)(transcriptPath, { force: true });
10077
10109
  }
10078
10110
  if (entry.summaryFile) {
10079
- const summaryPath = (0, import_node_path19.join)(this.dir, entry.summaryFile);
10080
- (0, import_node_fs23.rmSync)(summaryPath, { force: true });
10111
+ const summaryPath = (0, import_node_path20.join)(this.dir, entry.summaryFile);
10112
+ (0, import_node_fs24.rmSync)(summaryPath, { force: true });
10081
10113
  }
10082
10114
  if (opts?.localOnly) {
10083
10115
  entry.audioFile = void 0;
@@ -10135,34 +10167,34 @@ var RecordingStorage = class {
10135
10167
  * 获取音频文件的绝对路径。ossUrl 用于推断文件扩展名
10136
10168
  */
10137
10169
  getAudioFilePath(recordingId, ossUrl) {
10138
- return (0, import_node_path19.join)(this.audioDir, this.buildAudioFilename(recordingId, ossUrl));
10170
+ return (0, import_node_path20.join)(this.audioDir, this.buildAudioFilename(recordingId, ossUrl));
10139
10171
  }
10140
10172
  /**
10141
10173
  * 获取打点文件的绝对路径
10142
10174
  */
10143
10175
  getSrtFilePath(recordingId) {
10144
- return (0, import_node_path19.join)(this.audioDir, this.buildSrtFilename(recordingId));
10176
+ return (0, import_node_path20.join)(this.audioDir, this.buildSrtFilename(recordingId));
10145
10177
  }
10146
10178
  /**
10147
10179
  * 获取转写 JSON 文件的绝对路径
10148
10180
  */
10149
10181
  getTranscriptDataFilePath(recordingId) {
10150
- return (0, import_node_path19.join)(this.transcriptDataDir, this.buildTranscriptDataFilename(recordingId));
10182
+ return (0, import_node_path20.join)(this.transcriptDataDir, this.buildTranscriptDataFilename(recordingId));
10151
10183
  }
10152
10184
  /**
10153
10185
  * 获取摘要文件的绝对路径
10154
10186
  */
10155
10187
  getSummaryFilePath(recordingId) {
10156
- return (0, import_node_path19.join)(this.summariesDir, this.buildSummaryFilename(recordingId));
10188
+ return (0, import_node_path20.join)(this.summariesDir, this.buildSummaryFilename(recordingId));
10157
10189
  }
10158
10190
  // ─── Persistence ───
10159
10191
  loadIndex() {
10160
- if (!(0, import_node_fs23.existsSync)(this.indexPath)) {
10192
+ if (!(0, import_node_fs24.existsSync)(this.indexPath)) {
10161
10193
  this.index = { recordings: [] };
10162
10194
  return;
10163
10195
  }
10164
10196
  try {
10165
- const raw = JSON.parse((0, import_node_fs23.readFileSync)(this.indexPath, "utf-8"));
10197
+ const raw = JSON.parse((0, import_node_fs24.readFileSync)(this.indexPath, "utf-8"));
10166
10198
  if (raw && Array.isArray(raw.recordings)) {
10167
10199
  let needsRewrite = false;
10168
10200
  const normalized = raw.recordings.filter((entry) => entry && typeof entry === "object").map((entry) => {
@@ -10200,8 +10232,8 @@ var RecordingStorage = class {
10200
10232
  segments: []
10201
10233
  });
10202
10234
  const transcriptDataFilename = this.buildTranscriptDataFilename(compacted.id);
10203
- (0, import_node_fs23.writeFileSync)(
10204
- (0, import_node_path19.join)(this.transcriptDataDir, transcriptDataFilename),
10235
+ (0, import_node_fs24.writeFileSync)(
10236
+ (0, import_node_path20.join)(this.transcriptDataDir, transcriptDataFilename),
10205
10237
  JSON.stringify(transcriptDoc, null, 2),
10206
10238
  "utf-8"
10207
10239
  );
@@ -10213,8 +10245,8 @@ var RecordingStorage = class {
10213
10245
  compacted.summaryFile = entry.summaryFile;
10214
10246
  } else if (typeof entry.summary === "string" && entry.summary.trim()) {
10215
10247
  const summaryFilename = this.buildSummaryFilename(entry.id);
10216
- (0, import_node_fs23.writeFileSync)(
10217
- (0, import_node_path19.join)(this.summariesDir, summaryFilename),
10248
+ (0, import_node_fs24.writeFileSync)(
10249
+ (0, import_node_path20.join)(this.summariesDir, summaryFilename),
10218
10250
  entry.summary.trim(),
10219
10251
  "utf-8"
10220
10252
  );
@@ -10224,8 +10256,8 @@ var RecordingStorage = class {
10224
10256
  const summaryFromDocument = extractTranscriptSummaryFromDocument(transcriptDoc);
10225
10257
  if (summaryFromDocument) {
10226
10258
  const summaryFilename = this.buildSummaryFilename(entry.id);
10227
- (0, import_node_fs23.writeFileSync)(
10228
- (0, import_node_path19.join)(this.summariesDir, summaryFilename),
10259
+ (0, import_node_fs24.writeFileSync)(
10260
+ (0, import_node_path20.join)(this.summariesDir, summaryFilename),
10229
10261
  summaryFromDocument,
10230
10262
  "utf-8"
10231
10263
  );
@@ -10265,7 +10297,7 @@ var RecordingStorage = class {
10265
10297
  }
10266
10298
  readRelativeTextFile(relativePath) {
10267
10299
  try {
10268
- return (0, import_node_fs23.readFileSync)((0, import_node_path19.join)(this.dir, relativePath), "utf-8");
10300
+ return (0, import_node_fs24.readFileSync)((0, import_node_path20.join)(this.dir, relativePath), "utf-8");
10269
10301
  } catch {
10270
10302
  return void 0;
10271
10303
  }
@@ -10278,7 +10310,7 @@ var RecordingStorage = class {
10278
10310
  return parseTranscriptDocument(raw);
10279
10311
  }
10280
10312
  saveIndex() {
10281
- (0, import_node_fs23.writeFileSync)(
10313
+ (0, import_node_fs24.writeFileSync)(
10282
10314
  this.indexPath,
10283
10315
  JSON.stringify(this.index, null, 2),
10284
10316
  "utf-8"
@@ -10292,8 +10324,8 @@ var RecordingStorage = class {
10292
10324
  init_transcript_document();
10293
10325
 
10294
10326
  // src/recording/downloader.ts
10295
- var import_node_fs24 = require("fs");
10296
- var import_node_path20 = require("path");
10327
+ var import_node_fs25 = require("fs");
10328
+ var import_node_path21 = require("path");
10297
10329
  var import_promises2 = require("stream/promises");
10298
10330
  var import_node_stream = require("stream");
10299
10331
  var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -10303,7 +10335,7 @@ async function downloadFile(url, destPath, logger, options) {
10303
10335
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
10304
10336
  const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
10305
10337
  const retryBackoffMs = options?.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS;
10306
- (0, import_node_fs24.mkdirSync)((0, import_node_path20.dirname)(destPath), { recursive: true });
10338
+ (0, import_node_fs25.mkdirSync)((0, import_node_path21.dirname)(destPath), { recursive: true });
10307
10339
  let lastError;
10308
10340
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
10309
10341
  const startMs = Date.now();
@@ -10321,11 +10353,11 @@ async function downloadFile(url, destPath, logger, options) {
10321
10353
  if (!res.body) {
10322
10354
  throw new Error("\u54CD\u5E94\u4F53\u4E3A\u7A7A");
10323
10355
  }
10324
- const writeStream = (0, import_node_fs24.createWriteStream)(destPath);
10356
+ const writeStream = (0, import_node_fs25.createWriteStream)(destPath);
10325
10357
  const readable = import_node_stream.Readable.fromWeb(res.body);
10326
10358
  await (0, import_promises2.pipeline)(readable, writeStream);
10327
10359
  const elapsed = Date.now() - startMs;
10328
- const fileSize = (0, import_node_fs24.existsSync)(destPath) ? (0, import_node_fs24.statSync)(destPath).size : 0;
10360
+ const fileSize = (0, import_node_fs25.existsSync)(destPath) ? (0, import_node_fs25.statSync)(destPath).size : 0;
10329
10361
  logger.info(
10330
10362
  `[downloader] \u4E0B\u8F7D\u5B8C\u6210: ${destPath} (${formatBytes(fileSize)}, ${elapsed}ms)`
10331
10363
  );
@@ -10336,7 +10368,7 @@ async function downloadFile(url, destPath, logger, options) {
10336
10368
  } catch (err) {
10337
10369
  lastError = err?.message ?? String(err);
10338
10370
  try {
10339
- if ((0, import_node_fs24.existsSync)(destPath)) (0, import_node_fs24.unlinkSync)(destPath);
10371
+ if ((0, import_node_fs25.existsSync)(destPath)) (0, import_node_fs25.unlinkSync)(destPath);
10340
10372
  } catch {
10341
10373
  }
10342
10374
  const isAbort = err?.name === "AbortError";
@@ -10574,13 +10606,13 @@ async function triggerTranscription(recordingId, storage, asrConfig, logger, opt
10574
10606
  }
10575
10607
 
10576
10608
  // src/tunnel/service.ts
10577
- var import_node_fs29 = require("fs");
10578
- var import_node_path25 = require("path");
10609
+ var import_node_fs30 = require("fs");
10610
+ var import_node_path26 = require("path");
10579
10611
  init_credentials();
10580
10612
 
10581
10613
  // src/tunnel/relay-client.ts
10582
- var import_node_fs27 = require("fs");
10583
- var import_node_path23 = require("path");
10614
+ var import_node_fs28 = require("fs");
10615
+ var import_node_path24 = require("path");
10584
10616
 
10585
10617
  // node_modules/.pnpm/ws@8.19.0/node_modules/ws/wrapper.mjs
10586
10618
  var import_stream = __toESM(require_stream(), 1);
@@ -10624,8 +10656,8 @@ var RelayClient = class {
10624
10656
  lastDisconnectReason
10625
10657
  };
10626
10658
  try {
10627
- (0, import_node_fs27.mkdirSync)((0, import_node_path23.dirname)(this.opts.statusFilePath), { recursive: true });
10628
- (0, import_node_fs27.writeFileSync)(this.opts.statusFilePath, JSON.stringify(info, null, 2));
10659
+ (0, import_node_fs28.mkdirSync)((0, import_node_path24.dirname)(this.opts.statusFilePath), { recursive: true });
10660
+ (0, import_node_fs28.writeFileSync)(this.opts.statusFilePath, JSON.stringify(info, null, 2));
10629
10661
  } catch {
10630
10662
  }
10631
10663
  }
@@ -11007,8 +11039,8 @@ init_host();
11007
11039
 
11008
11040
  // src/tunnel/device-identity.ts
11009
11041
  var import_node_crypto3 = __toESM(require("crypto"), 1);
11010
- var import_node_fs28 = __toESM(require("fs"), 1);
11011
- var import_node_path24 = __toESM(require("path"), 1);
11042
+ var import_node_fs29 = __toESM(require("fs"), 1);
11043
+ var import_node_path25 = __toESM(require("path"), 1);
11012
11044
  init_host();
11013
11045
  var ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
11014
11046
  function base64UrlEncode(buf) {
@@ -11053,10 +11085,10 @@ function resolveClientStateDir(stateDir) {
11053
11085
  return stateDir ?? resolveStateDir();
11054
11086
  }
11055
11087
  function ensureDir(filePath) {
11056
- import_node_fs28.default.mkdirSync(import_node_path24.default.dirname(filePath), { recursive: true });
11088
+ import_node_fs29.default.mkdirSync(import_node_path25.default.dirname(filePath), { recursive: true });
11057
11089
  }
11058
11090
  function resolveIdentityPath(stateDir) {
11059
- return import_node_path24.default.join(stateDir, "identity", "device.json");
11091
+ return import_node_path25.default.join(stateDir, "identity", "device.json");
11060
11092
  }
11061
11093
  function normalizeDeviceAuthRole(role) {
11062
11094
  return role.trim();
@@ -11072,12 +11104,12 @@ function normalizeDeviceAuthScopes(scopes) {
11072
11104
  return [...out].sort();
11073
11105
  }
11074
11106
  function resolveDeviceAuthPath(stateDir) {
11075
- return import_node_path24.default.join(stateDir, "identity", "device-auth.json");
11107
+ return import_node_path25.default.join(stateDir, "identity", "device-auth.json");
11076
11108
  }
11077
11109
  function readDeviceAuthStore(filePath) {
11078
11110
  try {
11079
- if (!import_node_fs28.default.existsSync(filePath)) return null;
11080
- const raw = import_node_fs28.default.readFileSync(filePath, "utf8");
11111
+ if (!import_node_fs29.default.existsSync(filePath)) return null;
11112
+ const raw = import_node_fs29.default.readFileSync(filePath, "utf8");
11081
11113
  const parsed = JSON.parse(raw);
11082
11114
  if (parsed?.version !== 1 || typeof parsed.deviceId !== "string") return null;
11083
11115
  if (!parsed.tokens || typeof parsed.tokens !== "object") return null;
@@ -11088,12 +11120,12 @@ function readDeviceAuthStore(filePath) {
11088
11120
  }
11089
11121
  function writeDeviceAuthStore(filePath, store) {
11090
11122
  ensureDir(filePath);
11091
- import_node_fs28.default.writeFileSync(filePath, `${JSON.stringify(store, null, 2)}
11123
+ import_node_fs29.default.writeFileSync(filePath, `${JSON.stringify(store, null, 2)}
11092
11124
  `, {
11093
11125
  mode: 384
11094
11126
  });
11095
11127
  try {
11096
- import_node_fs28.default.chmodSync(filePath, 384);
11128
+ import_node_fs29.default.chmodSync(filePath, 384);
11097
11129
  } catch {
11098
11130
  }
11099
11131
  }
@@ -11140,8 +11172,8 @@ function clearDeviceAuthToken(params) {
11140
11172
  function loadOrCreateDeviceIdentity(stateDir) {
11141
11173
  const filePath = resolveIdentityPath(stateDir);
11142
11174
  try {
11143
- if (import_node_fs28.default.existsSync(filePath)) {
11144
- const raw = import_node_fs28.default.readFileSync(filePath, "utf8");
11175
+ if (import_node_fs29.default.existsSync(filePath)) {
11176
+ const raw = import_node_fs29.default.readFileSync(filePath, "utf8");
11145
11177
  const parsed = JSON.parse(raw);
11146
11178
  if (parsed?.version === 1 && typeof parsed.deviceId === "string" && typeof parsed.publicKeyPem === "string" && typeof parsed.privateKeyPem === "string") {
11147
11179
  const derivedId = fingerprintPublicKey(parsed.publicKeyPem);
@@ -11162,14 +11194,14 @@ function loadOrCreateDeviceIdentity(stateDir) {
11162
11194
  publicKeyPem,
11163
11195
  privateKeyPem
11164
11196
  };
11165
- import_node_fs28.default.mkdirSync(import_node_path24.default.dirname(filePath), { recursive: true });
11197
+ import_node_fs29.default.mkdirSync(import_node_path25.default.dirname(filePath), { recursive: true });
11166
11198
  const stored = {
11167
11199
  version: 1,
11168
11200
  ...identity,
11169
11201
  createdAtMs: Date.now()
11170
11202
  };
11171
11203
  ensureDir(filePath);
11172
- import_node_fs28.default.writeFileSync(filePath, `${JSON.stringify(stored, null, 2)}
11204
+ import_node_fs29.default.writeFileSync(filePath, `${JSON.stringify(stored, null, 2)}
11173
11205
  `, {
11174
11206
  mode: 384
11175
11207
  });
@@ -11939,7 +11971,7 @@ function createTunnelService(opts) {
11939
11971
  }
11940
11972
  function readLockOwner(filePath) {
11941
11973
  try {
11942
- const parsed = JSON.parse((0, import_node_fs29.readFileSync)(filePath, "utf-8"));
11974
+ const parsed = JSON.parse((0, import_node_fs30.readFileSync)(filePath, "utf-8"));
11943
11975
  return typeof parsed.pid === "number" ? parsed.pid : null;
11944
11976
  } catch {
11945
11977
  return null;
@@ -11952,23 +11984,23 @@ function createTunnelService(opts) {
11952
11984
  lockFd = null;
11953
11985
  if (fd !== null) {
11954
11986
  try {
11955
- (0, import_node_fs29.closeSync)(fd);
11987
+ (0, import_node_fs30.closeSync)(fd);
11956
11988
  } catch {
11957
11989
  }
11958
11990
  }
11959
11991
  if (filePath) {
11960
11992
  try {
11961
- (0, import_node_fs29.unlinkSync)(filePath);
11993
+ (0, import_node_fs30.unlinkSync)(filePath);
11962
11994
  } catch {
11963
11995
  }
11964
11996
  }
11965
11997
  }
11966
11998
  function acquireLock(filePath) {
11967
- (0, import_node_fs29.mkdirSync)((0, import_node_path25.dirname)(filePath), { recursive: true });
11999
+ (0, import_node_fs30.mkdirSync)((0, import_node_path26.dirname)(filePath), { recursive: true });
11968
12000
  for (let attempt = 0; attempt < 2; attempt++) {
11969
12001
  try {
11970
- const fd = (0, import_node_fs29.openSync)(filePath, "wx", 384);
11971
- (0, import_node_fs29.writeFileSync)(
12002
+ const fd = (0, import_node_fs30.openSync)(filePath, "wx", 384);
12003
+ (0, import_node_fs30.writeFileSync)(
11972
12004
  fd,
11973
12005
  JSON.stringify({
11974
12006
  pid: process.pid,
@@ -11992,7 +12024,7 @@ function createTunnelService(opts) {
11992
12024
  `Relay tunnel: removing stale local lock owned by dead pid=${ownerPid}`
11993
12025
  );
11994
12026
  try {
11995
- (0, import_node_fs29.unlinkSync)(filePath);
12027
+ (0, import_node_fs30.unlinkSync)(filePath);
11996
12028
  } catch {
11997
12029
  }
11998
12030
  continue;
@@ -12037,12 +12069,12 @@ function createTunnelService(opts) {
12037
12069
  return;
12038
12070
  }
12039
12071
  const { logger } = opts;
12040
- const baseStateDir = (0, import_node_path25.join)(ctx.stateDir, "plugins", "phone-notifications");
12072
+ const baseStateDir = (0, import_node_path26.join)(ctx.stateDir, "plugins", "phone-notifications");
12041
12073
  logger.info(
12042
12074
  `Relay tunnel: starting (pid=${process.pid}, url=${opts.tunnelUrl}, heartbeat=${opts.heartbeatSec ?? DEFAULT_HEARTBEAT_SEC}s, backoff=${opts.reconnectBackoffMs ?? DEFAULT_RECONNECT_BACKOFF_MS}ms, gateway=${opts.gatewayBaseUrl}, hasGatewayToken=${!!opts.gatewayToken}, hasGatewayPwd=${!!opts.gatewayPassword})`
12043
12075
  );
12044
- const statusFilePath = (0, import_node_path25.join)(baseStateDir, "tunnel-status.json");
12045
- const lockPath = (0, import_node_path25.join)(baseStateDir, "relay-tunnel.lock");
12076
+ const statusFilePath = (0, import_node_path26.join)(baseStateDir, "tunnel-status.json");
12077
+ const lockPath = (0, import_node_path26.join)(baseStateDir, "relay-tunnel.lock");
12046
12078
  if (!acquireLock(lockPath)) {
12047
12079
  return;
12048
12080
  }
@@ -12182,7 +12214,7 @@ function readHostGatewayConfig(params) {
12182
12214
  let configData;
12183
12215
  if (configPath) {
12184
12216
  try {
12185
- configData = JSON.parse((0, import_node_fs30.readFileSync)(configPath, "utf-8"));
12217
+ configData = JSON.parse((0, import_node_fs31.readFileSync)(configPath, "utf-8"));
12186
12218
  } catch (err) {
12187
12219
  if (err?.code !== "ENOENT") {
12188
12220
  params.logger.warn(