@yoooclaw/phone-notifications 1.11.1 → 1.11.2-beta.0

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
@@ -535,20 +535,20 @@ function selectModelByMemory(availableGB, isAppleSilicon = false) {
535
535
  return "tiny";
536
536
  }
537
537
  function resolveModelsDir(dataDir) {
538
- const dir = (0, import_node_path22.join)(dataDir, WHISPER_MODELS_DIR);
539
- (0, import_node_fs26.mkdirSync)(dir, { recursive: true });
538
+ const dir = (0, import_node_path21.join)(dataDir, WHISPER_MODELS_DIR);
539
+ (0, import_node_fs25.mkdirSync)(dir, { recursive: true });
540
540
  return dir;
541
541
  }
542
542
  function resolveBinDir(dataDir) {
543
- const dir = (0, import_node_path22.join)(dataDir, WHISPER_BIN_DIR);
544
- (0, import_node_fs26.mkdirSync)(dir, { recursive: true });
543
+ const dir = (0, import_node_path21.join)(dataDir, WHISPER_BIN_DIR);
544
+ (0, import_node_fs25.mkdirSync)(dir, { recursive: true });
545
545
  return dir;
546
546
  }
547
547
  function isModelDownloaded(modelsDir, modelSize) {
548
- const modelPath = (0, import_node_path22.join)(modelsDir, MODEL_FILENAMES[modelSize]);
549
- if (!(0, import_node_fs26.existsSync)(modelPath)) return false;
548
+ const modelPath = (0, import_node_path21.join)(modelsDir, MODEL_FILENAMES[modelSize]);
549
+ if (!(0, import_node_fs25.existsSync)(modelPath)) return false;
550
550
  try {
551
- const stat = (0, import_node_fs26.statSync)(modelPath);
551
+ const stat = (0, import_node_fs25.statSync)(modelPath);
552
552
  const expectedSize = MODEL_DISK_SIZES[modelSize];
553
553
  return stat.size >= expectedSize * 0.8;
554
554
  } catch {
@@ -557,7 +557,7 @@ function isModelDownloaded(modelsDir, modelSize) {
557
557
  }
558
558
  async function downloadModel(modelsDir, modelSize, logger, modelSource, mirrorUrl) {
559
559
  const filename = MODEL_FILENAMES[modelSize];
560
- const modelPath = (0, import_node_path22.join)(modelsDir, filename);
560
+ const modelPath = (0, import_node_path21.join)(modelsDir, filename);
561
561
  if (isModelDownloaded(modelsDir, modelSize)) {
562
562
  logger.info(`[whisper-local] \u6A21\u578B\u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u4E0B\u8F7D: ${filename}`);
563
563
  return { ok: true, modelPath };
@@ -623,7 +623,7 @@ async function probeUrl(url, logger) {
623
623
  async function downloadFromUrl(url, modelPath, logger) {
624
624
  const tmpPath = `${modelPath}.downloading`;
625
625
  try {
626
- (0, import_node_fs26.mkdirSync)((0, import_node_path22.dirname)(modelPath), { recursive: true });
626
+ (0, import_node_fs25.mkdirSync)((0, import_node_path21.dirname)(modelPath), { recursive: true });
627
627
  const controller = new AbortController();
628
628
  const timer = setTimeout(() => controller.abort(), 30 * 60 * 1e3);
629
629
  try {
@@ -639,7 +639,7 @@ async function downloadFromUrl(url, modelPath, logger) {
639
639
  return { ok: false, modelPath, error: "\u6A21\u578B\u4E0B\u8F7D\u5931\u8D25: \u54CD\u5E94\u4F53\u4E3A\u7A7A" };
640
640
  }
641
641
  const contentLength = Number(res.headers.get("content-length") ?? 0);
642
- const writeStream = (0, import_node_fs26.createWriteStream)(tmpPath);
642
+ const writeStream = (0, import_node_fs25.createWriteStream)(tmpPath);
643
643
  const readable = import_node_stream2.Readable.fromWeb(res.body);
644
644
  let downloaded = 0;
645
645
  let lastLogPercent = 0;
@@ -661,14 +661,14 @@ async function downloadFromUrl(url, modelPath, logger) {
661
661
  }
662
662
  const { renameSync: renameSync2 } = await import("fs");
663
663
  renameSync2(tmpPath, modelPath);
664
- const fileSize = (0, import_node_fs26.statSync)(modelPath).size;
664
+ const fileSize = (0, import_node_fs25.statSync)(modelPath).size;
665
665
  logger.info(
666
- `[whisper-local] \u6A21\u578B\u4E0B\u8F7D\u5B8C\u6210: ${(0, import_node_path22.basename)(modelPath)} (${formatBytes2(fileSize)})`
666
+ `[whisper-local] \u6A21\u578B\u4E0B\u8F7D\u5B8C\u6210: ${(0, import_node_path21.basename)(modelPath)} (${formatBytes2(fileSize)})`
667
667
  );
668
668
  return { ok: true, modelPath };
669
669
  } catch (err2) {
670
670
  try {
671
- if ((0, import_node_fs26.existsSync)(tmpPath)) (0, import_node_fs26.unlinkSync)(tmpPath);
671
+ if ((0, import_node_fs25.existsSync)(tmpPath)) (0, import_node_fs25.unlinkSync)(tmpPath);
672
672
  } catch {
673
673
  }
674
674
  const msg = err2?.name === "AbortError" ? "\u6A21\u578B\u4E0B\u8F7D\u8D85\u65F6\uFF0830 \u5206\u949F\uFF09" : err2?.message ?? String(err2);
@@ -680,8 +680,8 @@ function findWhisperBinary(dataDir, logger) {
680
680
  const binDir = resolveBinDir(dataDir);
681
681
  const binNames = (0, import_node_os4.platform)() === "win32" ? ["whisper-cli.exe", "whisper.exe", "main.exe"] : ["whisper-cli", "whisper", "main"];
682
682
  for (const name of binNames) {
683
- const binPath = (0, import_node_path22.join)(binDir, name);
684
- if ((0, import_node_fs26.existsSync)(binPath)) {
683
+ const binPath = (0, import_node_path21.join)(binDir, name);
684
+ if ((0, import_node_fs25.existsSync)(binPath)) {
685
685
  logger.info(`[whisper-local] \u627E\u5230\u672C\u5730\u4E8C\u8FDB\u5236: ${binPath}`);
686
686
  return binPath;
687
687
  }
@@ -732,7 +732,7 @@ async function transcribeWithWhisperLocal(audioFilePath, localConfig, dataDir, l
732
732
  return { ok: false, error: `\u6A21\u578B\u4E0B\u8F7D\u5931\u8D25: ${downloadResult.error}` };
733
733
  }
734
734
  }
735
- const modelPath = (0, import_node_path22.join)(modelsDir, MODEL_FILENAMES[modelSize]);
735
+ const modelPath = (0, import_node_path21.join)(modelsDir, MODEL_FILENAMES[modelSize]);
736
736
  let inputPath = audioFilePath;
737
737
  let tmpWavPath = null;
738
738
  const actualFmt = detectAudioFormat(audioFilePath);
@@ -784,10 +784,10 @@ async function transcribeWithWhisperLocal(audioFilePath, localConfig, dataDir, l
784
784
  logger.info(`[whisper-local] \u8F6C\u5199\u8017\u65F6: ${Math.round(elapsed / 1e3)}s`);
785
785
  const jsonPath = inputPath + ".json";
786
786
  let jsonContent;
787
- if ((0, import_node_fs26.existsSync)(jsonPath)) {
788
- jsonContent = (0, import_node_fs26.readFileSync)(jsonPath, "utf-8");
787
+ if ((0, import_node_fs25.existsSync)(jsonPath)) {
788
+ jsonContent = (0, import_node_fs25.readFileSync)(jsonPath, "utf-8");
789
789
  try {
790
- (0, import_node_fs26.unlinkSync)(jsonPath);
790
+ (0, import_node_fs25.unlinkSync)(jsonPath);
791
791
  } catch {
792
792
  }
793
793
  } else {
@@ -865,10 +865,10 @@ function getPhysicalCoreCount() {
865
865
  }
866
866
  function detectAudioFormat(filePath) {
867
867
  try {
868
- const fd = (0, import_node_fs26.openSync)(filePath, "r");
868
+ const fd = (0, import_node_fs25.openSync)(filePath, "r");
869
869
  const buf = Buffer.alloc(12);
870
- (0, import_node_fs26.readSync)(fd, buf, 0, 12, 0);
871
- (0, import_node_fs26.closeSync)(fd);
870
+ (0, import_node_fs25.readSync)(fd, buf, 0, 12, 0);
871
+ (0, import_node_fs25.closeSync)(fd);
872
872
  const header = buf.toString("ascii", 0, 4);
873
873
  const header8 = buf.toString("ascii", 0, 8);
874
874
  if (header === "RIFF" && buf.toString("ascii", 8, 12) === "WAVE") return ".wav";
@@ -903,7 +903,7 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
903
903
  timeout: 12e4,
904
904
  stdio: ["pipe", "pipe", "pipe"]
905
905
  });
906
- if (ffmpegResult.status === 0 && (0, import_node_fs26.existsSync)(outputPath)) {
906
+ if (ffmpegResult.status === 0 && (0, import_node_fs25.existsSync)(outputPath)) {
907
907
  logger.info(`[whisper-local] ffmpeg \u8F6C\u6362\u5B8C\u6210: ${outputPath}`);
908
908
  return { ok: true };
909
909
  }
@@ -916,7 +916,7 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
916
916
  ["--rate", "16000", "--mono", inputPath, outputPath],
917
917
  { encoding: "utf-8", timeout: 12e4, stdio: ["pipe", "pipe", "pipe"] }
918
918
  );
919
- if (opusResult.status === 0 && (0, import_node_fs26.existsSync)(outputPath)) {
919
+ if (opusResult.status === 0 && (0, import_node_fs25.existsSync)(outputPath)) {
920
920
  logger.info(`[whisper-local] opusdec \u8F6C\u6362\u5B8C\u6210: ${outputPath}`);
921
921
  return { ok: true };
922
922
  }
@@ -930,7 +930,7 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
930
930
  if (detectedExt && !inputPath.endsWith(detectedExt)) {
931
931
  tmpCopy = inputPath + ".detected" + detectedExt;
932
932
  try {
933
- (0, import_node_fs26.copyFileSync)(inputPath, tmpCopy);
933
+ (0, import_node_fs25.copyFileSync)(inputPath, tmpCopy);
934
934
  actualInputPath = tmpCopy;
935
935
  logger.info(
936
936
  `[whisper-local] \u68C0\u6D4B\u5230\u5B9E\u9645\u683C\u5F0F ${detectedExt}\uFF0C\u4E34\u65F6\u91CD\u547D\u540D`
@@ -954,22 +954,22 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
954
954
  timeout: 12e4,
955
955
  stdio: ["pipe", "pipe", "pipe"]
956
956
  });
957
- if (tmpCopy && (0, import_node_fs26.existsSync)(tmpCopy)) {
957
+ if (tmpCopy && (0, import_node_fs25.existsSync)(tmpCopy)) {
958
958
  try {
959
- (0, import_node_fs26.unlinkSync)(tmpCopy);
959
+ (0, import_node_fs25.unlinkSync)(tmpCopy);
960
960
  } catch {
961
961
  }
962
962
  }
963
- if (afResult.status === 0 && (0, import_node_fs26.existsSync)(outputPath)) {
963
+ if (afResult.status === 0 && (0, import_node_fs25.existsSync)(outputPath)) {
964
964
  logger.info(`[whisper-local] afconvert \u8F6C\u6362\u5B8C\u6210: ${outputPath}`);
965
965
  return { ok: true };
966
966
  }
967
967
  const stderr = afResult.stderr?.slice(0, 200) ?? "";
968
968
  return { ok: false, error: `afconvert \u8F6C\u6362\u5931\u8D25 (exit ${afResult.status}): ${stderr}` };
969
969
  } catch (err2) {
970
- if (tmpCopy && (0, import_node_fs26.existsSync)(tmpCopy)) {
970
+ if (tmpCopy && (0, import_node_fs25.existsSync)(tmpCopy)) {
971
971
  try {
972
- (0, import_node_fs26.unlinkSync)(tmpCopy);
972
+ (0, import_node_fs25.unlinkSync)(tmpCopy);
973
973
  } catch {
974
974
  }
975
975
  }
@@ -980,9 +980,9 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
980
980
  return { ok: false, error: `\u65E0\u6CD5\u5C06\u97F3\u9891\u8F6C\u6362\u4E3A WAV \u683C\u5F0F\u3002${fmtHint}` };
981
981
  }
982
982
  function cleanupTmpWav(path2) {
983
- if (path2 && (0, import_node_fs26.existsSync)(path2)) {
983
+ if (path2 && (0, import_node_fs25.existsSync)(path2)) {
984
984
  try {
985
- (0, import_node_fs26.unlinkSync)(path2);
985
+ (0, import_node_fs25.unlinkSync)(path2);
986
986
  } catch {
987
987
  }
988
988
  }
@@ -1068,13 +1068,13 @@ function formatBytes2(bytes) {
1068
1068
  if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
1069
1069
  return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)}GB`;
1070
1070
  }
1071
- 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;
1071
+ 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;
1072
1072
  var init_whisper_local = __esm({
1073
1073
  "src/recording/whisper-local.ts"() {
1074
1074
  "use strict";
1075
1075
  import_node_child_process2 = require("child_process");
1076
- import_node_fs26 = require("fs");
1077
- import_node_path22 = require("path");
1076
+ import_node_fs25 = require("fs");
1077
+ import_node_path21 = require("path");
1078
1078
  import_promises3 = require("stream/promises");
1079
1079
  import_node_stream2 = require("stream");
1080
1080
  import_node_os4 = require("os");
@@ -1229,7 +1229,7 @@ async function initializeAsr(config, dataDir, logger) {
1229
1229
  }
1230
1230
  }
1231
1231
  async function transcribeAudio(audioFilePath, config, logger, options = {}) {
1232
- if (!(0, import_node_fs27.existsSync)(audioFilePath)) {
1232
+ if (!(0, import_node_fs26.existsSync)(audioFilePath)) {
1233
1233
  return { ok: false, error: `\u97F3\u9891\u6587\u4EF6\u4E0D\u5B58\u5728: ${audioFilePath}` };
1234
1234
  }
1235
1235
  logger.info(
@@ -1240,6 +1240,7 @@ async function transcribeAudio(audioFilePath, config, logger, options = {}) {
1240
1240
  case "api":
1241
1241
  return await transcribeWithModelProxy(
1242
1242
  options.audioOssUrl,
1243
+ options.audioDurationMs,
1243
1244
  config.api,
1244
1245
  logger
1245
1246
  );
@@ -1339,7 +1340,8 @@ async function runTranscriptionWorkflow(params) {
1339
1340
  logger
1340
1341
  } = params;
1341
1342
  const result = await transcribeAudio(audioFilePath, config, logger, {
1342
- audioOssUrl
1343
+ audioOssUrl,
1344
+ audioDurationMs: Math.max(0, Math.round(durationSec * 1e3))
1343
1345
  });
1344
1346
  if (!result.ok) {
1345
1347
  return { ok: false, error: result.error };
@@ -1373,8 +1375,8 @@ async function runTranscriptionWorkflow(params) {
1373
1375
  createdAt
1374
1376
  );
1375
1377
  const transcriptDataFilename = buildTranscriptDataFilename(recordingId);
1376
- const transcriptDataPath = (0, import_node_path23.join)(transcriptDataDir, transcriptDataFilename);
1377
- (0, import_node_fs27.writeFileSync)(
1378
+ const transcriptDataPath = (0, import_node_path22.join)(transcriptDataDir, transcriptDataFilename);
1379
+ (0, import_node_fs26.writeFileSync)(
1378
1380
  transcriptDataPath,
1379
1381
  JSON.stringify(transcriptData, null, 2),
1380
1382
  "utf-8"
@@ -1382,14 +1384,14 @@ async function runTranscriptionWorkflow(params) {
1382
1384
  logger.info(`[asr] \u8F6C\u5199 JSON \u5DF2\u5199\u5165: ${transcriptDataPath}`);
1383
1385
  const safeSummary = title.replace(/[/\\:*?"<>|]/g, "").trim().slice(0, 20);
1384
1386
  const filename = safeSummary ? `${recordingId}_${safeSummary}.md` : `${recordingId}.md`;
1385
- const filePath = (0, import_node_path23.join)(transcriptsDir, filename);
1386
- (0, import_node_fs27.writeFileSync)(filePath, markdown, "utf-8");
1387
+ const filePath = (0, import_node_path22.join)(transcriptsDir, filename);
1388
+ (0, import_node_fs26.writeFileSync)(filePath, markdown, "utf-8");
1387
1389
  logger.info(`[asr] \u8F6C\u5199\u6587\u672C\u5DF2\u5199\u5165: ${filePath}`);
1388
1390
  let summaryFilename;
1389
1391
  if (summary) {
1390
1392
  summaryFilename = `${recordingId}.md`;
1391
- const summaryFilePath = (0, import_node_path23.join)(summariesDir, summaryFilename);
1392
- (0, import_node_fs27.writeFileSync)(summaryFilePath, summary, "utf-8");
1393
+ const summaryFilePath = (0, import_node_path22.join)(summariesDir, summaryFilename);
1394
+ (0, import_node_fs26.writeFileSync)(summaryFilePath, summary, "utf-8");
1393
1395
  logger.info(`[asr] \u6458\u8981\u6587\u672C\u5DF2\u5199\u5165: ${summaryFilePath}`);
1394
1396
  }
1395
1397
  return {
@@ -1402,7 +1404,7 @@ async function runTranscriptionWorkflow(params) {
1402
1404
  title
1403
1405
  };
1404
1406
  }
1405
- async function transcribeWithModelProxy(audioOssUrl, apiConfig, logger) {
1407
+ async function transcribeWithModelProxy(audioOssUrl, audioDurationMs, apiConfig, logger) {
1406
1408
  const normalizedAudioOssUrl = normalizeOptionalText2(audioOssUrl);
1407
1409
  if (!normalizedAudioOssUrl) {
1408
1410
  return { ok: false, error: "API \u6A21\u5F0F\u7F3A\u5C11 audioOssUrl\uFF0C\u65E0\u6CD5\u8C03\u7528 model-proxy" };
@@ -1468,13 +1470,14 @@ async function transcribeWithModelProxy(audioOssUrl, apiConfig, logger) {
1468
1470
  apiKey,
1469
1471
  taskId,
1470
1472
  initialRequestId: requestId,
1473
+ audioDurationMs,
1471
1474
  apiConfig,
1472
1475
  logger
1473
1476
  });
1474
1477
  }
1475
1478
  async function transcribeWithWhisperLocal2(audioFilePath, config, logger) {
1476
1479
  const { transcribeWithWhisperLocal: runLocal } = await Promise.resolve().then(() => (init_whisper_local(), whisper_local_exports));
1477
- const dataDir = process.env.OPENCLAW_STATE_DIR ?? process.env.QCLAW_STATE_DIR ?? (0, import_node_path23.join)(audioFilePath, "..", "..", "..");
1480
+ const dataDir = process.env.OPENCLAW_STATE_DIR ?? process.env.QCLAW_STATE_DIR ?? (0, import_node_path22.join)(audioFilePath, "..", "..", "..");
1478
1481
  const localConfig = config.local ?? {};
1479
1482
  const result = await runLocal(
1480
1483
  audioFilePath,
@@ -1530,6 +1533,7 @@ async function pollLongRecordingTaskResult(params) {
1530
1533
  apiKey,
1531
1534
  taskId,
1532
1535
  initialRequestId,
1536
+ audioDurationMs,
1533
1537
  apiConfig,
1534
1538
  logger
1535
1539
  } = params;
@@ -1577,7 +1581,13 @@ async function pollLongRecordingTaskResult(params) {
1577
1581
  lastStatus = status;
1578
1582
  }
1579
1583
  if (status === "SUCCEEDED") {
1580
- return buildLongRecordingSuccessResult(taskId, requestId, data, logger);
1584
+ return buildLongRecordingSuccessResult(
1585
+ taskId,
1586
+ requestId,
1587
+ data,
1588
+ audioDurationMs,
1589
+ logger
1590
+ );
1581
1591
  }
1582
1592
  if (LONG_RECORDING_TERMINAL_FAILURE_STATUSES.has(status)) {
1583
1593
  return {
@@ -1600,11 +1610,11 @@ async function pollLongRecordingTaskResult(params) {
1600
1610
  error: `Model Proxy ASR \u8F6E\u8BE2\u8D85\u65F6: taskId=${taskId}, waited=${DEFAULT_LONG_RECORDING_MAX_POLL_ATTEMPTS * DEFAULT_LONG_RECORDING_POLL_INTERVAL_MS}ms`
1601
1611
  };
1602
1612
  }
1603
- function buildLongRecordingSuccessResult(taskId, requestId, data, logger) {
1613
+ function buildLongRecordingSuccessResult(taskId, requestId, data, audioDurationMs, logger) {
1604
1614
  const sourceTextList = normalizeLongRecordingSourceTextList(
1605
1615
  data?.recordResult?.sourceTextList
1606
1616
  );
1607
- const listResult = extractLongRecordingTextFromList(sourceTextList);
1617
+ const listResult = extractLongRecordingTextFromList(sourceTextList, audioDurationMs);
1608
1618
  const sourceText = normalizeOptionalText2(data?.recordResult?.sourceText);
1609
1619
  const summaryText = normalizeOptionalText2(data?.recordResult?.summaryResult) ?? "";
1610
1620
  const title = normalizeOptionalText2(data?.recordResult?.title);
@@ -1701,11 +1711,12 @@ function normalizeLongRecordingSourceTextList(value) {
1701
1711
  return [{
1702
1712
  content,
1703
1713
  speakerId: normalizeOptionalInteger2(record.speakerId),
1704
- startTime: normalizeOptionalNonNegativeNumber(record.startTime)
1714
+ startTime: normalizeOptionalNonNegativeNumber(record.startTime),
1715
+ endTime: normalizeOptionalNonNegativeNumber(record.endTime)
1705
1716
  }];
1706
1717
  });
1707
1718
  }
1708
- function extractLongRecordingTextFromList(items) {
1719
+ function extractLongRecordingTextFromList(items, finalFallbackEndMs) {
1709
1720
  if (items.length === 0) {
1710
1721
  return {
1711
1722
  segments: []
@@ -1713,10 +1724,13 @@ function extractLongRecordingTextFromList(items) {
1713
1724
  }
1714
1725
  const segments = items.map((item, index) => {
1715
1726
  const startMs = item.startTime ?? 0;
1727
+ const explicitEndMs = item.endTime;
1716
1728
  const nextStart = items[index + 1]?.startTime;
1729
+ const fallbackEndMs = index === items.length - 1 ? normalizeOptionalNonNegativeNumber(finalFallbackEndMs) : void 0;
1730
+ const endMs = explicitEndMs ?? nextStart ?? fallbackEndMs ?? startMs;
1717
1731
  return {
1718
1732
  start_ms: startMs,
1719
- end_ms: nextStart ?? startMs,
1733
+ end_ms: Math.max(startMs, endMs),
1720
1734
  text: item.content,
1721
1735
  speaker_id: item.speakerId
1722
1736
  };
@@ -1772,12 +1786,12 @@ function formatTranscriptSegmentText(segment) {
1772
1786
  }
1773
1787
  return text;
1774
1788
  }
1775
- 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;
1789
+ 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;
1776
1790
  var init_asr = __esm({
1777
1791
  "src/recording/asr.ts"() {
1778
1792
  "use strict";
1779
- import_node_fs27 = require("fs");
1780
- import_node_path23 = require("path");
1793
+ import_node_fs26 = require("fs");
1794
+ import_node_path22 = require("path");
1781
1795
  init_credentials();
1782
1796
  init_env();
1783
1797
  init_transcript_document();
@@ -5422,7 +5436,7 @@ function readBuildInjectedVersion() {
5422
5436
  if (false) {
5423
5437
  return void 0;
5424
5438
  }
5425
- const version = "1.11.1".trim();
5439
+ const version = "1.11.2-beta.0".trim();
5426
5440
  return version || void 0;
5427
5441
  }
5428
5442
  function readPluginVersionFromPackageJson() {
@@ -6035,20 +6049,17 @@ function readOptionalString(value) {
6035
6049
  const trimmed = value.trim();
6036
6050
  return trimmed || void 0;
6037
6051
  }
6038
- function isLegacyLightRuleWithoutType(raw) {
6039
- return raw.type === void 0 && readOptionalString(raw.name) !== void 0 && readOptionalString(raw.description) !== void 0 && Array.isArray(raw.segments);
6040
- }
6041
6052
  function readMeta(taskDir) {
6042
6053
  const metaPath = (0, import_node_path3.join)(taskDir, "meta.json");
6043
6054
  if (!(0, import_node_fs4.existsSync)(metaPath)) return null;
6044
6055
  try {
6045
6056
  const raw = JSON.parse((0, import_node_fs4.readFileSync)(metaPath, "utf-8"));
6046
6057
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
6047
- if (raw.type !== "light-rule" && !isLegacyLightRuleWithoutType(raw)) return null;
6058
+ if (raw.type !== "light-rule") return null;
6048
6059
  if (!Array.isArray(raw.segments)) return null;
6049
6060
  const name = readOptionalString(raw.name) ?? (0, import_node_path3.basename)(taskDir);
6050
6061
  const title = readOptionalString(raw.title) ?? name;
6051
- const description = readOptionalString(raw.description) ?? readOptionalString(raw.reason) ?? name;
6062
+ const description = readOptionalString(raw.description) ?? name;
6052
6063
  const createdAt = readOptionalString(raw.createdAt) ?? (0, import_node_fs4.statSync)(metaPath).birthtime.toISOString();
6053
6064
  const enabled = typeof raw.enabled === "boolean" ? raw.enabled : true;
6054
6065
  const repeatTimes = normalizeRepeatTimes({
@@ -7075,115 +7086,6 @@ var InlineLightRuleEvaluator = class {
7075
7086
  }
7076
7087
  };
7077
7088
 
7078
- // src/light-rules/migration.ts
7079
- var import_node_fs8 = require("fs");
7080
- var import_node_path7 = require("path");
7081
- var NO_MATCH_FETCH_PY = `#!/usr/bin/env python3
7082
- # \u6B64\u6587\u4EF6\u7531\u8FC1\u79FB\u5DE5\u5177\u751F\u6210\u3002
7083
- # \u706F\u6548\u89C4\u5219\u5DF2\u8FC1\u79FB\u81F3\u4E8B\u4EF6\u9A71\u52A8\u67B6\u6784\uFF0C\u6B64 cron job \u4E0D\u518D\u6267\u884C\u5B9E\u9645\u5DE5\u4F5C\u3002
7084
- print("NO_MATCH")
7085
- `;
7086
- function normalizeScriptText(text) {
7087
- return text.replace(/\r\n/g, "\n").trim();
7088
- }
7089
- function resolveTasksDir(ctx) {
7090
- if (ctx.workspaceDir) return (0, import_node_path7.join)(ctx.workspaceDir, "tasks");
7091
- if (ctx.stateDir) {
7092
- const inferredWorkspaceDir = (0, import_node_path7.join)(ctx.stateDir, "workspace");
7093
- if ((0, import_node_fs8.existsSync)(inferredWorkspaceDir)) return (0, import_node_path7.join)(inferredWorkspaceDir, "tasks");
7094
- return (0, import_node_path7.join)(ctx.stateDir, "tasks");
7095
- }
7096
- return null;
7097
- }
7098
- function migrateLegacyLightRuleTasks(ctx, logger) {
7099
- const tasksDir3 = resolveTasksDir(ctx);
7100
- if (!tasksDir3 || !(0, import_node_fs8.existsSync)(tasksDir3)) return;
7101
- try {
7102
- for (const entry of (0, import_node_fs8.readdirSync)(tasksDir3, { withFileTypes: true })) {
7103
- if (!entry.isDirectory()) continue;
7104
- migrateTaskDir((0, import_node_path7.join)(tasksDir3, String(entry.name)), logger);
7105
- }
7106
- } catch (err2) {
7107
- logger.warn(`migration: failed to read tasks dir: ${err2?.message}`);
7108
- }
7109
- }
7110
- function migrateTaskDir(taskDir, logger) {
7111
- const metaPath = (0, import_node_path7.join)(taskDir, "meta.json");
7112
- if (!(0, import_node_fs8.existsSync)(metaPath)) return;
7113
- let meta;
7114
- try {
7115
- meta = JSON.parse((0, import_node_fs8.readFileSync)(metaPath, "utf-8"));
7116
- } catch {
7117
- return;
7118
- }
7119
- if (meta.type !== "light-rule") return;
7120
- const name = typeof meta.name === "string" ? meta.name : taskDir;
7121
- cleanupLegacyMetaFields(meta, name, metaPath, logger);
7122
- replaceFetchPy(taskDir, name, logger);
7123
- for (const filename of ["README.md", "checkpoint.json"]) {
7124
- removeFile((0, import_node_path7.join)(taskDir, filename), name, filename, logger);
7125
- }
7126
- }
7127
- function cleanupLegacyMetaFields(meta, name, metaPath, logger) {
7128
- const cleaned = [];
7129
- if (mergeMatchRulesIntoDescription(meta)) cleaned.push("matchRules");
7130
- if (meta.cronSchedule !== void 0) {
7131
- delete meta.cronSchedule;
7132
- cleaned.push("cronSchedule");
7133
- }
7134
- if (cleaned.length === 0) return;
7135
- try {
7136
- (0, import_node_fs8.writeFileSync)(metaPath, JSON.stringify(meta, null, 2), "utf-8");
7137
- logger.info(
7138
- `migration: cleaned deprecated field(s) [${cleaned.join(", ")}] in meta.json for light rule: ${name}`
7139
- );
7140
- } catch (err2) {
7141
- logger.warn(`migration: failed to update meta.json for ${name}: ${err2?.message}`);
7142
- }
7143
- }
7144
- function mergeMatchRulesIntoDescription(meta) {
7145
- const matchRules = meta.matchRules;
7146
- if (!matchRules || typeof matchRules !== "object") return false;
7147
- const rules = matchRules;
7148
- const parts = [];
7149
- if (rules.appName) parts.push(`app=${rules.appName}`);
7150
- if (rules.senderKeywords?.length) {
7151
- parts.push(`\u53D1\u4EF6\u4EBA\u5173\u952E\u8BCD=${rules.senderKeywords.join("\u3001")}`);
7152
- }
7153
- if (rules.contentKeywords?.length) {
7154
- parts.push(`\u5185\u5BB9\u5173\u952E\u8BCD=${rules.contentKeywords.join("\u3001")}`);
7155
- }
7156
- if (parts.length > 0) {
7157
- const existing = typeof meta.description === "string" ? meta.description.trim() : "";
7158
- meta.description = existing ? `${existing}\u3002\u5339\u914D\u89C4\u5219\uFF1A${parts.join("\uFF0C")}` : `\u5339\u914D\u89C4\u5219\uFF1A${parts.join("\uFF0C")}`;
7159
- }
7160
- delete meta.matchRules;
7161
- return true;
7162
- }
7163
- function replaceFetchPy(taskDir, name, logger) {
7164
- const fetchPyPath = (0, import_node_path7.join)(taskDir, "fetch.py");
7165
- if (!(0, import_node_fs8.existsSync)(fetchPyPath)) return;
7166
- try {
7167
- const existing = (0, import_node_fs8.readFileSync)(fetchPyPath, "utf-8");
7168
- if (normalizeScriptText(existing) === normalizeScriptText(NO_MATCH_FETCH_PY)) {
7169
- return;
7170
- }
7171
- (0, import_node_fs8.writeFileSync)(fetchPyPath, NO_MATCH_FETCH_PY, "utf-8");
7172
- logger.info(`migration: replaced fetch.py with NO_MATCH placeholder for ${name}`);
7173
- } catch (err2) {
7174
- logger.warn(`migration: failed to replace fetch.py for ${name}: ${err2?.message}`);
7175
- }
7176
- }
7177
- function removeFile(filePath, ruleName, filename, logger) {
7178
- if (!(0, import_node_fs8.existsSync)(filePath)) return;
7179
- try {
7180
- (0, import_node_fs8.rmSync)(filePath);
7181
- logger.info(`migration: removed ${filename} for light rule: ${ruleName}`);
7182
- } catch (err2) {
7183
- logger.warn(`migration: failed to remove ${filename} for ${ruleName}: ${err2?.message}`);
7184
- }
7185
- }
7186
-
7187
7089
  // src/light-rules/pi-invoker.ts
7188
7090
  var import_agent_runtime = require("openclaw/plugin-sdk/agent-runtime");
7189
7091
  var DEFAULT_PROVIDER = "anthropic";
@@ -7365,7 +7267,7 @@ function resolveUpdateChannel(params) {
7365
7267
  }
7366
7268
 
7367
7269
  // src/update/index.ts
7368
- var import_node_path9 = require("path");
7270
+ var import_node_path8 = require("path");
7369
7271
 
7370
7272
  // src/update/checker.ts
7371
7273
  function parseSemver(v) {
@@ -7467,8 +7369,8 @@ var UpdateChecker = class {
7467
7369
  };
7468
7370
 
7469
7371
  // src/update/executor.ts
7470
- var import_node_fs9 = require("fs");
7471
- var import_node_path8 = require("path");
7372
+ var import_node_fs8 = require("fs");
7373
+ var import_node_path7 = require("path");
7472
7374
  var import_node_os = require("os");
7473
7375
  var VERSION_PATTERN = /^\d+\.\d+\.\d+(-[\w.]+)?$/;
7474
7376
  var BASE_URL = "https://artifact.yoooclaw.com/plugin";
@@ -7478,9 +7380,9 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7478
7380
  }
7479
7381
  const tgzUrl = `${BASE_URL}/v${version}/yoooclaw-phone-notifications-${version}.tgz`;
7480
7382
  logger.info(`\u6267\u884C\u66F4\u65B0: ${tgzUrl} \u2192 ${targetDir}`);
7481
- const workDir = (0, import_node_fs9.mkdtempSync)((0, import_node_path8.join)((0, import_node_os.tmpdir)(), ".openclaw-plugin-update-"));
7482
- const tgzPath = (0, import_node_path8.join)(workDir, "plugin.tgz");
7483
- const stagingDir = (0, import_node_path8.join)(workDir, "staged");
7383
+ const workDir = (0, import_node_fs8.mkdtempSync)((0, import_node_path7.join)((0, import_node_os.tmpdir)(), ".openclaw-plugin-update-"));
7384
+ const tgzPath = (0, import_node_path7.join)(workDir, "plugin.tgz");
7385
+ const stagingDir = (0, import_node_path7.join)(workDir, "staged");
7484
7386
  let backupDir = null;
7485
7387
  try {
7486
7388
  logger.info("\u4E0B\u8F7D\u63D2\u4EF6\u5305...");
@@ -7489,9 +7391,9 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7489
7391
  return { success: false, message: `\u4E0B\u8F7D\u5931\u8D25 (HTTP ${response.status}): ${tgzUrl}` };
7490
7392
  }
7491
7393
  const buffer = Buffer.from(await response.arrayBuffer());
7492
- (0, import_node_fs9.writeFileSync)(tgzPath, buffer);
7394
+ (0, import_node_fs8.writeFileSync)(tgzPath, buffer);
7493
7395
  logger.info(`\u4E0B\u8F7D\u5B8C\u6210 (${buffer.length} bytes)`);
7494
- (0, import_node_fs9.mkdirSync)(stagingDir, { recursive: true });
7396
+ (0, import_node_fs8.mkdirSync)(stagingDir, { recursive: true });
7495
7397
  const tarResult = await runCommand(
7496
7398
  ["tar", "-xzf", tgzPath, "-C", stagingDir, "--strip-components=1"],
7497
7399
  { timeoutMs: 3e4 }
@@ -7500,14 +7402,14 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7500
7402
  const err2 = tarResult.stderr || tarResult.stdout || "unknown error";
7501
7403
  return { success: false, message: `\u89E3\u538B\u5931\u8D25: ${err2}` };
7502
7404
  }
7503
- (0, import_node_fs9.mkdirSync)((0, import_node_path8.dirname)(targetDir), { recursive: true });
7405
+ (0, import_node_fs8.mkdirSync)((0, import_node_path7.dirname)(targetDir), { recursive: true });
7504
7406
  try {
7505
7407
  backupDir = `${targetDir}.bak.${Date.now()}`;
7506
- (0, import_node_fs9.renameSync)(targetDir, backupDir);
7408
+ (0, import_node_fs8.renameSync)(targetDir, backupDir);
7507
7409
  } catch {
7508
7410
  backupDir = null;
7509
7411
  }
7510
- (0, import_node_fs9.renameSync)(stagingDir, targetDir);
7412
+ (0, import_node_fs8.renameSync)(stagingDir, targetDir);
7511
7413
  try {
7512
7414
  await updateConfigRecord2(version, tgzUrl);
7513
7415
  } catch (err2) {
@@ -7515,18 +7417,18 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7515
7417
  }
7516
7418
  if (backupDir) {
7517
7419
  try {
7518
- (0, import_node_fs9.rmSync)(backupDir, { force: true, recursive: true });
7420
+ (0, import_node_fs8.rmSync)(backupDir, { force: true, recursive: true });
7519
7421
  } catch {
7520
7422
  }
7521
7423
  }
7522
- const msg = `\u5DF2\u66F4\u65B0\u5230 ${version}\uFF0C\u8BF7\u91CD\u542F gateway \u751F\u6548`;
7424
+ const msg = `\u5DF2\u66F4\u65B0\u5230 ${version}`;
7523
7425
  logger.info(msg);
7524
- return { success: true, message: msg };
7426
+ return { success: true, message: msg, version };
7525
7427
  } catch (err2) {
7526
7428
  if (backupDir) {
7527
7429
  try {
7528
- (0, import_node_fs9.rmSync)(targetDir, { force: true, recursive: true });
7529
- (0, import_node_fs9.renameSync)(backupDir, targetDir);
7430
+ (0, import_node_fs8.rmSync)(targetDir, { force: true, recursive: true });
7431
+ (0, import_node_fs8.renameSync)(backupDir, targetDir);
7530
7432
  logger.info("\u5DF2\u56DE\u6EDA\u5230\u4E4B\u524D\u7248\u672C");
7531
7433
  } catch (rollbackErr) {
7532
7434
  logger.error(`\u56DE\u6EDA\u5931\u8D25: ${String(rollbackErr)}`);
@@ -7537,12 +7439,47 @@ async function executeUpdate(version, runCommand, logger, targetDir, updateConfi
7537
7439
  return { success: false, message: errMsg };
7538
7440
  } finally {
7539
7441
  try {
7540
- (0, import_node_fs9.rmSync)(workDir, { force: true, recursive: true });
7442
+ (0, import_node_fs8.rmSync)(workDir, { force: true, recursive: true });
7541
7443
  } catch {
7542
7444
  }
7543
7445
  }
7544
7446
  }
7545
7447
 
7448
+ // src/update/restart.ts
7449
+ function scheduleGatewayRestart(logger, deps = {}) {
7450
+ try {
7451
+ const cfg = deps.loadConfig?.();
7452
+ if (cfg?.commands?.restart === false) {
7453
+ logger.warn("\u66F4\u65B0\u540E\u8DF3\u8FC7 gateway \u91CD\u542F: commands.restart=false");
7454
+ return { scheduled: false };
7455
+ }
7456
+ } catch (err2) {
7457
+ logger.warn(`\u66F4\u65B0\u540E\u68C0\u67E5 gateway \u91CD\u542F\u914D\u7F6E\u5931\u8D25: ${String(err2)}`);
7458
+ }
7459
+ const getListenerCount = deps.getListenerCount ?? ((signal) => process.listenerCount(signal));
7460
+ if (getListenerCount("SIGUSR1") < 1) {
7461
+ logger.warn("\u66F4\u65B0\u540E\u8DF3\u8FC7 gateway \u91CD\u542F: \u5F53\u524D\u8FDB\u7A0B\u672A\u6CE8\u518C SIGUSR1 \u76D1\u542C\u5668");
7462
+ return { scheduled: false };
7463
+ }
7464
+ const emitSignal = deps.emitSignal ?? ((signal) => process.emit(signal));
7465
+ const schedule = deps.schedule ?? ((task) => {
7466
+ setTimeout(task, 0);
7467
+ });
7468
+ schedule(() => {
7469
+ try {
7470
+ const accepted = emitSignal("SIGUSR1");
7471
+ if (accepted) {
7472
+ logger.info("\u66F4\u65B0\u5B8C\u6210\uFF0C\u5DF2\u89E6\u53D1 gateway SIGUSR1 \u91CD\u542F");
7473
+ } else {
7474
+ logger.warn("\u66F4\u65B0\u5B8C\u6210\uFF0C\u4F46 gateway SIGUSR1 \u4FE1\u53F7\u672A\u88AB\u5904\u7406");
7475
+ }
7476
+ } catch (err2) {
7477
+ logger.warn(`\u66F4\u65B0\u540E\u89E6\u53D1 gateway \u91CD\u542F\u5931\u8D25: ${String(err2)}`);
7478
+ }
7479
+ });
7480
+ return { scheduled: true };
7481
+ }
7482
+
7546
7483
  // src/update/index.ts
7547
7484
  var PLUGIN_ID = "phone-notifications";
7548
7485
  function resolveTargetDir(api) {
@@ -7552,7 +7489,7 @@ function resolveTargetDir(api) {
7552
7489
  if (installPath) return installPath;
7553
7490
  } catch {
7554
7491
  }
7555
- return (0, import_node_path9.join)(api.runtime.state.resolveStateDir(), "extensions", PLUGIN_ID);
7492
+ return (0, import_node_path8.join)(api.runtime.state.resolveStateDir(), "extensions", PLUGIN_ID);
7556
7493
  }
7557
7494
  async function updateConfigRecord(api, version, targetDir, tgzUrl) {
7558
7495
  const configApi = api.runtime.config;
@@ -7570,6 +7507,23 @@ async function updateConfigRecord(api, version, targetDir, tgzUrl) {
7570
7507
  };
7571
7508
  await configApi.writeConfigFile(cfg);
7572
7509
  }
7510
+ function finalizeUpdateResult(api, logger, result) {
7511
+ if (!result.success) {
7512
+ return result;
7513
+ }
7514
+ const restart = scheduleGatewayRestart(logger, {
7515
+ loadConfig: () => {
7516
+ const configApi = api.runtime.config;
7517
+ return configApi?.loadConfig?.();
7518
+ }
7519
+ });
7520
+ const version = result.version ?? "\u76EE\u6807\u7248\u672C";
7521
+ return {
7522
+ ...result,
7523
+ restartScheduled: restart.scheduled,
7524
+ message: restart.scheduled ? `\u5DF2\u66F4\u65B0\u5230 ${version}\uFF0C\u5DF2\u89E6\u53D1 gateway \u91CD\u542F` : `\u5DF2\u66F4\u65B0\u5230 ${version}\uFF0C\u8BF7\u624B\u52A8\u91CD\u542F gateway \u751F\u6548`
7525
+ };
7526
+ }
7573
7527
  function registerAutoUpdate(api, logger, config, getBroadcast, rememberBroadcast, externalUpdateNotifier) {
7574
7528
  if (config.enabled === false) {
7575
7529
  logger.info("\u81EA\u52A8\u66F4\u65B0\u5DF2\u7981\u7528 (autoUpdate.enabled = false)");
@@ -7601,7 +7555,7 @@ function registerAutoUpdate(api, logger, config, getBroadcast, rememberBroadcast
7601
7555
  api.registerTool({
7602
7556
  name: "plugin-update",
7603
7557
  label: "Plugin Update",
7604
- description: "\u5C06 phone-notifications \u63D2\u4EF6\u66F4\u65B0\u5230\u6307\u5B9A\u7248\u672C\u3002\u4EC5\u5728\u7528\u6237\u660E\u786E\u540C\u610F\u66F4\u65B0\u540E\u8C03\u7528\u3002\u66F4\u65B0\u5B8C\u6210\u540E\u9700\u91CD\u542F gateway \u751F\u6548\u3002",
7558
+ description: "\u5C06 phone-notifications \u63D2\u4EF6\u66F4\u65B0\u5230\u6307\u5B9A\u7248\u672C\u3002\u4EC5\u5728\u7528\u6237\u660E\u786E\u540C\u610F\u66F4\u65B0\u540E\u8C03\u7528\u3002\u66F4\u65B0\u5B8C\u6210\u540E\u4F1A\u81EA\u52A8\u5C1D\u8BD5\u91CD\u542F gateway\uFF1B\u5982\u5BBF\u4E3B\u4E0D\u652F\u6301\uFF0C\u5219\u9700\u624B\u52A8\u91CD\u542F\u3002",
7605
7559
  parameters: {
7606
7560
  type: "object",
7607
7561
  required: ["version"],
@@ -7623,13 +7577,14 @@ function registerAutoUpdate(api, logger, config, getBroadcast, rememberBroadcast
7623
7577
  targetDir,
7624
7578
  (v, url) => updateConfigRecord(api, v, targetDir, url)
7625
7579
  );
7626
- if (result.success) {
7580
+ const finalResult = finalizeUpdateResult(api, logger, result);
7581
+ if (finalResult.success) {
7627
7582
  pendingUpdate = null;
7628
7583
  externalUpdateNotifier?.clearPendingUpdate();
7629
7584
  }
7630
7585
  return {
7631
- content: [{ type: "text", text: result.message }],
7632
- details: result
7586
+ content: [{ type: "text", text: finalResult.message }],
7587
+ details: finalResult
7633
7588
  };
7634
7589
  }
7635
7590
  });
@@ -7651,16 +7606,20 @@ function registerAutoUpdate(api, logger, config, getBroadcast, rememberBroadcast
7651
7606
  targetDir,
7652
7607
  (v, url) => updateConfigRecord(api, v, targetDir, url)
7653
7608
  );
7654
- if (result.success) {
7609
+ const finalResult = finalizeUpdateResult(api, logger, result);
7610
+ if (finalResult.success) {
7655
7611
  pendingUpdate = null;
7656
7612
  externalUpdateNotifier?.clearPendingUpdate();
7657
7613
  }
7658
- if (result.success) {
7659
- respond(true, { message: result.message });
7614
+ if (finalResult.success) {
7615
+ respond(true, {
7616
+ message: finalResult.message,
7617
+ restartScheduled: finalResult.restartScheduled === true
7618
+ });
7660
7619
  } else {
7661
7620
  respond(false, void 0, {
7662
7621
  code: "UPDATE_FAILED",
7663
- message: result.message
7622
+ message: finalResult.message
7664
7623
  });
7665
7624
  }
7666
7625
  });
@@ -7740,10 +7699,10 @@ function registerAutoUpdateLifecycle(deps) {
7740
7699
  }
7741
7700
 
7742
7701
  // src/plugin/cli.ts
7743
- var import_node_path17 = require("path");
7702
+ var import_node_path16 = require("path");
7744
7703
 
7745
7704
  // src/cli/auth.ts
7746
- var import_node_fs10 = require("fs");
7705
+ var import_node_fs9 = require("fs");
7747
7706
  init_credentials();
7748
7707
  function registerAuthCli(program) {
7749
7708
  const auth = program.command("auth").description("\u7528\u6237\u8BA4\u8BC1\u7BA1\u7406");
@@ -7779,12 +7738,12 @@ function registerAuthCli(program) {
7779
7738
  });
7780
7739
  auth.command("clear").description("\u6E05\u9664\u5DF2\u4FDD\u5B58\u7684\u8BA4\u8BC1\u4FE1\u606F").action(() => {
7781
7740
  const path2 = credentialsPath();
7782
- if ((0, import_node_fs10.existsSync)(path2)) {
7741
+ if ((0, import_node_fs9.existsSync)(path2)) {
7783
7742
  const creds = readCredentials();
7784
7743
  delete creds.apiKey;
7785
7744
  delete creds.token;
7786
7745
  if (Object.keys(creds).length === 0) {
7787
- (0, import_node_fs10.rmSync)(path2, { force: true });
7746
+ (0, import_node_fs9.rmSync)(path2, { force: true });
7788
7747
  } else {
7789
7748
  writeCredentials(creds);
7790
7749
  }
@@ -7916,23 +7875,23 @@ function registerNtfStats(ntf, ctx) {
7916
7875
  }
7917
7876
 
7918
7877
  // src/cli/ntf-sync.ts
7919
- var import_node_fs11 = require("fs");
7920
- var import_node_path10 = require("path");
7878
+ var import_node_fs10 = require("fs");
7879
+ var import_node_path9 = require("path");
7921
7880
  var SYNC_FETCH_LIMIT = 300;
7922
7881
  function checkpointPath(dir) {
7923
- return (0, import_node_path10.join)(dir, ".checkpoint.json");
7882
+ return (0, import_node_path9.join)(dir, ".checkpoint.json");
7924
7883
  }
7925
7884
  function readCheckpoint(dir) {
7926
7885
  const p = checkpointPath(dir);
7927
- if (!(0, import_node_fs11.existsSync)(p)) return {};
7886
+ if (!(0, import_node_fs10.existsSync)(p)) return {};
7928
7887
  try {
7929
- return JSON.parse((0, import_node_fs11.readFileSync)(p, "utf-8"));
7888
+ return JSON.parse((0, import_node_fs10.readFileSync)(p, "utf-8"));
7930
7889
  } catch {
7931
7890
  return {};
7932
7891
  }
7933
7892
  }
7934
7893
  function writeCheckpoint(dir, data) {
7935
- (0, import_node_fs11.writeFileSync)(checkpointPath(dir), JSON.stringify(data, null, 2), "utf-8");
7894
+ (0, import_node_fs10.writeFileSync)(checkpointPath(dir), JSON.stringify(data, null, 2), "utf-8");
7936
7895
  }
7937
7896
  function registerNtfSync(ntf, ctx) {
7938
7897
  const sync = ntf.command("sync").description("\u540C\u6B65\u901A\u77E5\u5230\u8BB0\u5FC6\u7CFB\u7EDF");
@@ -8025,8 +7984,8 @@ function registerNtfSync(ntf, ctx) {
8025
7984
  }
8026
7985
 
8027
7986
  // src/cli/ntf-monitor.ts
8028
- var import_node_fs12 = require("fs");
8029
- var import_node_path11 = require("path");
7987
+ var import_node_fs11 = require("fs");
7988
+ var import_node_path10 = require("path");
8030
7989
 
8031
7990
  // src/monitor/fetch-gen.ts
8032
7991
  function generateFetchPy(name, matchRules) {
@@ -8111,19 +8070,19 @@ function pyLiteral(value) {
8111
8070
  function tasksDir2(ctx) {
8112
8071
  const base = ctx.workspaceDir || ctx.stateDir;
8113
8072
  if (!base) throw new Error("workspaceDir and stateDir both unavailable");
8114
- return (0, import_node_path11.join)(base, "tasks");
8073
+ return (0, import_node_path10.join)(base, "tasks");
8115
8074
  }
8116
8075
  function readMeta2(taskDir) {
8117
- const metaPath = (0, import_node_path11.join)(taskDir, "meta.json");
8118
- if (!(0, import_node_fs12.existsSync)(metaPath)) return null;
8076
+ const metaPath = (0, import_node_path10.join)(taskDir, "meta.json");
8077
+ if (!(0, import_node_fs11.existsSync)(metaPath)) return null;
8119
8078
  try {
8120
- return JSON.parse((0, import_node_fs12.readFileSync)(metaPath, "utf-8"));
8079
+ return JSON.parse((0, import_node_fs11.readFileSync)(metaPath, "utf-8"));
8121
8080
  } catch {
8122
8081
  return null;
8123
8082
  }
8124
8083
  }
8125
8084
  function writeMeta2(taskDir, meta) {
8126
- (0, import_node_fs12.writeFileSync)((0, import_node_path11.join)(taskDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8");
8085
+ (0, import_node_fs11.writeFileSync)((0, import_node_path10.join)(taskDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8");
8127
8086
  }
8128
8087
  function generateReadme(name, description) {
8129
8088
  return `# Monitor Task: ${name}
@@ -8142,27 +8101,27 @@ function registerNtfMonitor(ntf, ctx) {
8142
8101
  const monitor = ntf.command("monitor").description("\u901A\u77E5\u76D1\u63A7\u4EFB\u52A1\u7BA1\u7406");
8143
8102
  monitor.command("list").description("\u5217\u51FA\u6240\u6709\u76D1\u63A7\u4EFB\u52A1").action(() => {
8144
8103
  const dir = tasksDir2(ctx);
8145
- if (!(0, import_node_fs12.existsSync)(dir)) {
8104
+ if (!(0, import_node_fs11.existsSync)(dir)) {
8146
8105
  output({ ok: true, tasks: [] });
8147
8106
  return;
8148
8107
  }
8149
8108
  const tasks = [];
8150
- for (const entry of (0, import_node_fs12.readdirSync)(dir, { withFileTypes: true })) {
8109
+ for (const entry of (0, import_node_fs11.readdirSync)(dir, { withFileTypes: true })) {
8151
8110
  if (!entry.isDirectory()) continue;
8152
- const meta = readMeta2((0, import_node_path11.join)(dir, entry.name));
8111
+ const meta = readMeta2((0, import_node_path10.join)(dir, entry.name));
8153
8112
  if (meta) tasks.push(meta);
8154
8113
  }
8155
8114
  output({ ok: true, tasks });
8156
8115
  });
8157
8116
  monitor.command("show <name>").description("\u67E5\u770B\u76D1\u63A7\u4EFB\u52A1\u8BE6\u60C5").action((name) => {
8158
- const taskDir = (0, import_node_path11.join)(tasksDir2(ctx), name);
8117
+ const taskDir = (0, import_node_path10.join)(tasksDir2(ctx), name);
8159
8118
  const meta = readMeta2(taskDir);
8160
8119
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
8161
- const checkpointPath2 = (0, import_node_path11.join)(taskDir, "checkpoint.json");
8120
+ const checkpointPath2 = (0, import_node_path10.join)(taskDir, "checkpoint.json");
8162
8121
  let checkpoint = {};
8163
- if ((0, import_node_fs12.existsSync)(checkpointPath2)) {
8122
+ if ((0, import_node_fs11.existsSync)(checkpointPath2)) {
8164
8123
  try {
8165
- checkpoint = JSON.parse((0, import_node_fs12.readFileSync)(checkpointPath2, "utf-8"));
8124
+ checkpoint = JSON.parse((0, import_node_fs11.readFileSync)(checkpointPath2, "utf-8"));
8166
8125
  } catch {
8167
8126
  }
8168
8127
  }
@@ -8177,8 +8136,8 @@ function registerNtfMonitor(ntf, ctx) {
8177
8136
  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(
8178
8137
  (name, opts) => {
8179
8138
  const dir = tasksDir2(ctx);
8180
- const taskDir = (0, import_node_path11.join)(dir, name);
8181
- if ((0, import_node_fs12.existsSync)(taskDir)) {
8139
+ const taskDir = (0, import_node_path10.join)(dir, name);
8140
+ if ((0, import_node_fs11.existsSync)(taskDir)) {
8182
8141
  exitError("ALREADY_EXISTS", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u5DF2\u5B58\u5728`);
8183
8142
  }
8184
8143
  let matchRules;
@@ -8190,7 +8149,7 @@ function registerNtfMonitor(ntf, ctx) {
8190
8149
  "match-rules \u5FC5\u987B\u662F\u5408\u6CD5\u7684 JSON"
8191
8150
  );
8192
8151
  }
8193
- (0, import_node_fs12.mkdirSync)(taskDir, { recursive: true });
8152
+ (0, import_node_fs11.mkdirSync)(taskDir, { recursive: true });
8194
8153
  const meta = {
8195
8154
  name,
8196
8155
  description: opts.description,
@@ -8200,13 +8159,13 @@ function registerNtfMonitor(ntf, ctx) {
8200
8159
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
8201
8160
  };
8202
8161
  writeMeta2(taskDir, meta);
8203
- (0, import_node_fs12.writeFileSync)(
8204
- (0, import_node_path11.join)(taskDir, "fetch.py"),
8162
+ (0, import_node_fs11.writeFileSync)(
8163
+ (0, import_node_path10.join)(taskDir, "fetch.py"),
8205
8164
  generateFetchPy(name, matchRules),
8206
8165
  "utf-8"
8207
8166
  );
8208
- (0, import_node_fs12.writeFileSync)(
8209
- (0, import_node_path11.join)(taskDir, "README.md"),
8167
+ (0, import_node_fs11.writeFileSync)(
8168
+ (0, import_node_path10.join)(taskDir, "README.md"),
8210
8169
  generateReadme(name, opts.description),
8211
8170
  "utf-8"
8212
8171
  );
@@ -8234,8 +8193,8 @@ function registerNtfMonitor(ntf, ctx) {
8234
8193
  }
8235
8194
  );
8236
8195
  monitor.command("delete <name>").description("\u5220\u9664\u76D1\u63A7\u4EFB\u52A1").option("--yes", "\u8DF3\u8FC7\u786E\u8BA4").action((name, opts) => {
8237
- const taskDir = (0, import_node_path11.join)(tasksDir2(ctx), name);
8238
- if (!(0, import_node_fs12.existsSync)(taskDir)) {
8196
+ const taskDir = (0, import_node_path10.join)(tasksDir2(ctx), name);
8197
+ if (!(0, import_node_fs11.existsSync)(taskDir)) {
8239
8198
  exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
8240
8199
  }
8241
8200
  if (!opts.yes) {
@@ -8248,7 +8207,7 @@ function registerNtfMonitor(ntf, ctx) {
8248
8207
  });
8249
8208
  process.exit(1);
8250
8209
  }
8251
- (0, import_node_fs12.rmSync)(taskDir, { recursive: true, force: true });
8210
+ (0, import_node_fs11.rmSync)(taskDir, { recursive: true, force: true });
8252
8211
  output({
8253
8212
  ok: true,
8254
8213
  name,
@@ -8260,7 +8219,7 @@ function registerNtfMonitor(ntf, ctx) {
8260
8219
  });
8261
8220
  });
8262
8221
  monitor.command("enable <name>").description("\u542F\u7528\u76D1\u63A7\u4EFB\u52A1").action((name) => {
8263
- const taskDir = (0, import_node_path11.join)(tasksDir2(ctx), name);
8222
+ const taskDir = (0, import_node_path10.join)(tasksDir2(ctx), name);
8264
8223
  const meta = readMeta2(taskDir);
8265
8224
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
8266
8225
  meta.enabled = true;
@@ -8268,7 +8227,7 @@ function registerNtfMonitor(ntf, ctx) {
8268
8227
  output({ ok: true, name, enabled: true });
8269
8228
  });
8270
8229
  monitor.command("disable <name>").description("\u6682\u505C\u76D1\u63A7\u4EFB\u52A1").action((name) => {
8271
- const taskDir = (0, import_node_path11.join)(tasksDir2(ctx), name);
8230
+ const taskDir = (0, import_node_path10.join)(tasksDir2(ctx), name);
8272
8231
  const meta = readMeta2(taskDir);
8273
8232
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
8274
8233
  meta.enabled = false;
@@ -8312,9 +8271,9 @@ function registerLightSend(light) {
8312
8271
  }
8313
8272
 
8314
8273
  // src/cli/light-setup-tools.ts
8315
- var import_node_fs13 = require("fs");
8274
+ var import_node_fs12 = require("fs");
8316
8275
  var import_node_os2 = require("os");
8317
- var import_node_path12 = require("path");
8276
+ var import_node_path11 = require("path");
8318
8277
  function isObject(value) {
8319
8278
  return !!value && typeof value === "object" && !Array.isArray(value);
8320
8279
  }
@@ -8328,7 +8287,7 @@ function ensureArray(obj, key) {
8328
8287
  function resolveConfigPath2() {
8329
8288
  const fromEnv = process.env.OPENCLAW_CONFIG_PATH?.trim();
8330
8289
  if (fromEnv) return fromEnv;
8331
- return (0, import_node_path12.join)((0, import_node_os2.homedir)(), ".openclaw", "openclaw.json");
8290
+ return (0, import_node_path11.join)((0, import_node_os2.homedir)(), ".openclaw", "openclaw.json");
8332
8291
  }
8333
8292
  var LIGHT_TOOLS = [
8334
8293
  "light_control",
@@ -8375,12 +8334,12 @@ function upsertLightControlAlsoAllow(cfg) {
8375
8334
  function registerLightSetupTools(light) {
8376
8335
  light.command("setup").description("\u81EA\u52A8\u653E\u884C light_control\uFF08\u5199\u5165 tools.alsoAllow \u4E0E agents.main.tools.alsoAllow\uFF09").action(() => {
8377
8336
  const configPath = resolveConfigPath2();
8378
- if (!(0, import_node_fs13.existsSync)(configPath)) {
8337
+ if (!(0, import_node_fs12.existsSync)(configPath)) {
8379
8338
  exitError("CONFIG_NOT_FOUND", `\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6: ${configPath}`);
8380
8339
  }
8381
8340
  let cfg = {};
8382
8341
  try {
8383
- const raw = (0, import_node_fs13.readFileSync)(configPath, "utf-8");
8342
+ const raw = (0, import_node_fs12.readFileSync)(configPath, "utf-8");
8384
8343
  const parsed = JSON.parse(raw);
8385
8344
  if (isObject(parsed)) cfg = parsed;
8386
8345
  } catch (err2) {
@@ -8388,8 +8347,8 @@ function registerLightSetupTools(light) {
8388
8347
  }
8389
8348
  const result = upsertLightControlAlsoAllow(cfg);
8390
8349
  try {
8391
- (0, import_node_fs13.mkdirSync)((0, import_node_path12.dirname)(configPath), { recursive: true });
8392
- (0, import_node_fs13.writeFileSync)(configPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
8350
+ (0, import_node_fs12.mkdirSync)((0, import_node_path11.dirname)(configPath), { recursive: true });
8351
+ (0, import_node_fs12.writeFileSync)(configPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
8393
8352
  } catch (err2) {
8394
8353
  exitError("WRITE_FAILED", `\u5199\u5165\u914D\u7F6E\u5931\u8D25: ${err2?.message ?? String(err2)}`);
8395
8354
  }
@@ -8407,17 +8366,17 @@ function registerLightSetupTools(light) {
8407
8366
  }
8408
8367
 
8409
8368
  // src/cli/tunnel-status.ts
8410
- var import_node_fs14 = require("fs");
8411
- var import_node_path13 = require("path");
8369
+ var import_node_fs13 = require("fs");
8370
+ var import_node_path12 = require("path");
8412
8371
  init_credentials();
8413
8372
  init_env();
8414
- var STATUS_REL_PATH = (0, import_node_path13.join)("plugins", "phone-notifications", "tunnel-status.json");
8373
+ var STATUS_REL_PATH = (0, import_node_path12.join)("plugins", "phone-notifications", "tunnel-status.json");
8415
8374
  function readTunnelStatus(ctx) {
8416
8375
  if (!ctx.stateDir) return null;
8417
- const filePath = (0, import_node_path13.join)(ctx.stateDir, STATUS_REL_PATH);
8418
- if (!(0, import_node_fs14.existsSync)(filePath)) return null;
8376
+ const filePath = (0, import_node_path12.join)(ctx.stateDir, STATUS_REL_PATH);
8377
+ if (!(0, import_node_fs13.existsSync)(filePath)) return null;
8419
8378
  try {
8420
- return JSON.parse((0, import_node_fs14.readFileSync)(filePath, "utf-8"));
8379
+ return JSON.parse((0, import_node_fs13.readFileSync)(filePath, "utf-8"));
8421
8380
  } catch {
8422
8381
  return null;
8423
8382
  }
@@ -8485,24 +8444,24 @@ function registerNtfStoragePath(ntf, ctx) {
8485
8444
  }
8486
8445
 
8487
8446
  // src/cli/log-search.ts
8488
- var import_node_fs15 = require("fs");
8489
- var import_node_path14 = require("path");
8447
+ var import_node_fs14 = require("fs");
8448
+ var import_node_path13 = require("path");
8490
8449
  function resolveLogsDir(ctx) {
8491
8450
  if (ctx.stateDir) {
8492
- const dir = (0, import_node_path14.join)(
8451
+ const dir = (0, import_node_path13.join)(
8493
8452
  ctx.stateDir,
8494
8453
  "plugins",
8495
8454
  "phone-notifications",
8496
8455
  "logs"
8497
8456
  );
8498
- if ((0, import_node_fs15.existsSync)(dir)) return dir;
8457
+ if ((0, import_node_fs14.existsSync)(dir)) return dir;
8499
8458
  }
8500
8459
  return null;
8501
8460
  }
8502
8461
  function listLogDateKeys(dir) {
8503
8462
  const pattern = /^(\d{4}-\d{2}-\d{2})\.log$/;
8504
8463
  const keys = [];
8505
- for (const entry of (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true })) {
8464
+ for (const entry of (0, import_node_fs14.readdirSync)(dir, { withFileTypes: true })) {
8506
8465
  if (!entry.isFile()) continue;
8507
8466
  const m = pattern.exec(entry.name);
8508
8467
  if (m) keys.push(m[1]);
@@ -8510,9 +8469,9 @@ function listLogDateKeys(dir) {
8510
8469
  return keys.sort().reverse();
8511
8470
  }
8512
8471
  function collectLogLines(dir, dateKey, keyword, limit, collected) {
8513
- const filePath = (0, import_node_path14.join)(dir, `${dateKey}.log`);
8514
- if (!(0, import_node_fs15.existsSync)(filePath)) return;
8515
- const content = (0, import_node_fs15.readFileSync)(filePath, "utf-8");
8472
+ const filePath = (0, import_node_path13.join)(dir, `${dateKey}.log`);
8473
+ if (!(0, import_node_fs14.existsSync)(filePath)) return;
8474
+ const content = (0, import_node_fs14.readFileSync)(filePath, "utf-8");
8516
8475
  const lowerKeyword = keyword?.toLowerCase();
8517
8476
  for (const line of content.split("\n")) {
8518
8477
  if (collected.length >= limit) return;
@@ -8579,12 +8538,12 @@ function registerEnvCli(ntf) {
8579
8538
  }
8580
8539
 
8581
8540
  // src/cli/doctor.ts
8582
- var import_node_fs19 = require("fs");
8541
+ var import_node_fs18 = require("fs");
8583
8542
  var import_node_readline = require("readline");
8584
8543
  init_host();
8585
8544
 
8586
8545
  // src/cli/doctor/check-dangerous-flags.ts
8587
- var import_node_fs16 = require("fs");
8546
+ var import_node_fs15 = require("fs");
8588
8547
  function isObject2(v) {
8589
8548
  return !!v && typeof v === "object" && !Array.isArray(v);
8590
8549
  }
@@ -8601,13 +8560,13 @@ var checkDangerousFlags = ({ cfg, configPath }) => {
8601
8560
  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",
8602
8561
  fixDescription: "\u8BBE\u4E3A false",
8603
8562
  fix: () => {
8604
- const raw = (0, import_node_fs16.readFileSync)(configPath, "utf-8");
8563
+ const raw = (0, import_node_fs15.readFileSync)(configPath, "utf-8");
8605
8564
  const config = JSON.parse(raw);
8606
8565
  const gw = config.gateway;
8607
8566
  const cui = gw.controlUi;
8608
8567
  cui.dangerouslyDisableDeviceAuth = false;
8609
- (0, import_node_fs16.copyFileSync)(configPath, configPath + ".bak");
8610
- (0, import_node_fs16.writeFileSync)(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
8568
+ (0, import_node_fs15.copyFileSync)(configPath, configPath + ".bak");
8569
+ (0, import_node_fs15.writeFileSync)(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
8611
8570
  }
8612
8571
  };
8613
8572
  };
@@ -8655,11 +8614,11 @@ function warnEmpty() {
8655
8614
  }
8656
8615
 
8657
8616
  // src/cli/doctor/check-state-dir-perms.ts
8658
- var import_node_fs17 = require("fs");
8617
+ var import_node_fs16 = require("fs");
8659
8618
  var checkStateDirPerms = ({ stateDir }) => {
8660
8619
  let mode;
8661
8620
  try {
8662
- mode = (0, import_node_fs17.statSync)(stateDir).mode;
8621
+ mode = (0, import_node_fs16.statSync)(stateDir).mode;
8663
8622
  } catch {
8664
8623
  return null;
8665
8624
  }
@@ -8673,7 +8632,7 @@ var checkStateDirPerms = ({ stateDir }) => {
8673
8632
  detail: "\u5176\u4ED6\u7528\u6237\u53EF\u4EE5\u8BFB\u53D6\u8BE5\u76EE\u5F55\u4E0B\u7684\u51ED\u8BC1\u548C\u914D\u7F6E\u6587\u4EF6\u3002",
8674
8633
  fixDescription: "chmod 700 " + stateDir,
8675
8634
  fix: () => {
8676
- (0, import_node_fs17.chmodSync)(stateDir, 448);
8635
+ (0, import_node_fs16.chmodSync)(stateDir, 448);
8677
8636
  }
8678
8637
  };
8679
8638
  };
@@ -8728,16 +8687,16 @@ var checkCredentials = () => {
8728
8687
  };
8729
8688
 
8730
8689
  // src/cli/doctor/check-tunnel.ts
8731
- var import_node_fs18 = require("fs");
8732
- var import_node_path15 = require("path");
8733
- var STATUS_REL_PATH2 = (0, import_node_path15.join)(
8690
+ var import_node_fs17 = require("fs");
8691
+ var import_node_path14 = require("path");
8692
+ var STATUS_REL_PATH2 = (0, import_node_path14.join)(
8734
8693
  "plugins",
8735
8694
  "phone-notifications",
8736
8695
  "tunnel-status.json"
8737
8696
  );
8738
8697
  var checkTunnel = ({ stateDir }) => {
8739
- const filePath = (0, import_node_path15.join)(stateDir, STATUS_REL_PATH2);
8740
- if (!(0, import_node_fs18.existsSync)(filePath)) {
8698
+ const filePath = (0, import_node_path14.join)(stateDir, STATUS_REL_PATH2);
8699
+ if (!(0, import_node_fs17.existsSync)(filePath)) {
8741
8700
  return {
8742
8701
  id: "tunnel",
8743
8702
  severity: "warn",
@@ -8749,7 +8708,7 @@ var checkTunnel = ({ stateDir }) => {
8749
8708
  }
8750
8709
  let status;
8751
8710
  try {
8752
- status = JSON.parse((0, import_node_fs18.readFileSync)(filePath, "utf-8"));
8711
+ status = JSON.parse((0, import_node_fs17.readFileSync)(filePath, "utf-8"));
8753
8712
  } catch {
8754
8713
  return {
8755
8714
  id: "tunnel",
@@ -8842,9 +8801,9 @@ function isObject5(v) {
8842
8801
  return !!v && typeof v === "object" && !Array.isArray(v);
8843
8802
  }
8844
8803
  function readConfig(configPath) {
8845
- if (!(0, import_node_fs19.existsSync)(configPath)) return {};
8804
+ if (!(0, import_node_fs18.existsSync)(configPath)) return {};
8846
8805
  try {
8847
- const parsed = JSON.parse((0, import_node_fs19.readFileSync)(configPath, "utf-8"));
8806
+ const parsed = JSON.parse((0, import_node_fs18.readFileSync)(configPath, "utf-8"));
8848
8807
  return isObject5(parsed) ? parsed : {};
8849
8808
  } catch {
8850
8809
  return {};
@@ -9045,7 +9004,7 @@ function registerRecStoragePath(rec, ctx) {
9045
9004
 
9046
9005
  // src/cli/rec-setup.ts
9047
9006
  var import_node_readline2 = require("readline");
9048
- var import_node_fs20 = require("fs");
9007
+ var import_node_fs19 = require("fs");
9049
9008
  function ask(rl, question) {
9050
9009
  return new Promise((resolve) => rl.question(question, resolve));
9051
9010
  }
@@ -9131,9 +9090,9 @@ async function setupLocal(rl) {
9131
9090
  function registerRecSetup(rec, ctx) {
9132
9091
  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 () => {
9133
9092
  const configPath = resolveAsrConfigPath(ctx);
9134
- if ((0, import_node_fs20.existsSync)(configPath)) {
9093
+ if ((0, import_node_fs19.existsSync)(configPath)) {
9135
9094
  try {
9136
- const existing = JSON.parse((0, import_node_fs20.readFileSync)(configPath, "utf-8"));
9095
+ const existing = JSON.parse((0, import_node_fs19.readFileSync)(configPath, "utf-8"));
9137
9096
  process.stderr.write(`\u5F53\u524D\u5DF2\u6709\u914D\u7F6E\uFF1Amode = ${existing.mode}`);
9138
9097
  if (existing.updatedAt) process.stderr.write(`\uFF0C\u66F4\u65B0\u4E8E ${existing.updatedAt}`);
9139
9098
  process.stderr.write("\n");
@@ -9146,7 +9105,7 @@ function registerRecSetup(rec, ctx) {
9146
9105
  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"]);
9147
9106
  const config = modeIdx === 0 ? await setupApi(rl) : await setupLocal(rl);
9148
9107
  const stored = { ...config, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
9149
- (0, import_node_fs20.writeFileSync)(configPath, JSON.stringify(stored, null, 2), "utf-8");
9108
+ (0, import_node_fs19.writeFileSync)(configPath, JSON.stringify(stored, null, 2), "utf-8");
9150
9109
  process.stderr.write(`
9151
9110
  \u2713 \u914D\u7F6E\u5DF2\u4FDD\u5B58\u5230 ${configPath}
9152
9111
 
@@ -9160,8 +9119,8 @@ function registerRecSetup(rec, ctx) {
9160
9119
 
9161
9120
  // src/cli/update.ts
9162
9121
  var import_node_child_process = require("child_process");
9163
- var import_node_fs21 = require("fs");
9164
- var import_node_path16 = require("path");
9122
+ var import_node_fs20 = require("fs");
9123
+ var import_node_path15 = require("path");
9165
9124
  var import_node_os3 = __toESM(require("os"), 1);
9166
9125
  init_host();
9167
9126
  var BASE_URL2 = "https://artifact.yoooclaw.com/plugin";
@@ -9220,9 +9179,9 @@ async function runUpdate(ctx, opts) {
9220
9179
  `);
9221
9180
  process.exit(1);
9222
9181
  }
9223
- const tmpScript = (0, import_node_path16.join)(import_node_os3.default.tmpdir(), `openclaw-install-${Date.now()}.mjs`);
9182
+ const tmpScript = (0, import_node_path15.join)(import_node_os3.default.tmpdir(), `openclaw-install-${Date.now()}.mjs`);
9224
9183
  try {
9225
- (0, import_node_fs21.writeFileSync)(tmpScript, installScript, "utf-8");
9184
+ (0, import_node_fs20.writeFileSync)(tmpScript, installScript, "utf-8");
9226
9185
  } catch (err2) {
9227
9186
  const msg = `\u5199\u5165\u4E34\u65F6\u6587\u4EF6\u5931\u8D25: ${err2?.message ?? String(err2)}`;
9228
9187
  if (json) {
@@ -9240,7 +9199,7 @@ async function runUpdate(ctx, opts) {
9240
9199
  { stdio: "inherit" }
9241
9200
  );
9242
9201
  try {
9243
- (0, import_node_fs21.unlinkSync)(tmpScript);
9202
+ (0, import_node_fs20.unlinkSync)(tmpScript);
9244
9203
  } catch {
9245
9204
  }
9246
9205
  if (result.error) {
@@ -9304,10 +9263,10 @@ function inferOpenClawRootDir(workspaceDir) {
9304
9263
  if (!workspaceDir) {
9305
9264
  return void 0;
9306
9265
  }
9307
- if ((0, import_node_path17.basename)(workspaceDir) !== "workspace") {
9266
+ if ((0, import_node_path16.basename)(workspaceDir) !== "workspace") {
9308
9267
  return void 0;
9309
9268
  }
9310
- return (0, import_node_path17.dirname)(workspaceDir);
9269
+ return (0, import_node_path16.dirname)(workspaceDir);
9311
9270
  }
9312
9271
  function registerPluginCli(api, params) {
9313
9272
  const { logger, openclawDir } = params;
@@ -9558,12 +9517,12 @@ function registerLightControlTool(api, logger) {
9558
9517
  }
9559
9518
 
9560
9519
  // src/plugin/lifecycle.ts
9561
- var import_node_fs31 = require("fs");
9520
+ var import_node_fs30 = require("fs");
9562
9521
  init_host();
9563
9522
 
9564
9523
  // src/notification/app-name-map.ts
9565
- var import_node_fs22 = require("fs");
9566
- var import_node_path18 = require("path");
9524
+ var import_node_fs21 = require("fs");
9525
+ var import_node_path17 = require("path");
9567
9526
  init_credentials();
9568
9527
  init_env();
9569
9528
  var PLUGIN_STATE_DIR = "phone-notifications";
@@ -9584,7 +9543,7 @@ function isAppNameMapApiResponse(v) {
9584
9543
  );
9585
9544
  }
9586
9545
  function getCachePath(stateDir) {
9587
- return (0, import_node_path18.join)(stateDir, "plugins", PLUGIN_STATE_DIR, CACHE_FILE);
9546
+ return (0, import_node_path17.join)(stateDir, "plugins", PLUGIN_STATE_DIR, CACHE_FILE);
9588
9547
  }
9589
9548
  function createAppNameMapProvider(opts) {
9590
9549
  const { stateDir, logger } = opts;
@@ -9596,9 +9555,9 @@ function createAppNameMapProvider(opts) {
9596
9555
  let inFlightFetch = null;
9597
9556
  function loadFromDisk() {
9598
9557
  const path2 = getCachePath(stateDir);
9599
- if (!(0, import_node_fs22.existsSync)(path2)) return;
9558
+ if (!(0, import_node_fs21.existsSync)(path2)) return;
9600
9559
  try {
9601
- const raw = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf-8"));
9560
+ const raw = JSON.parse((0, import_node_fs21.readFileSync)(path2, "utf-8"));
9602
9561
  if (!isRecordOfStrings(raw)) return;
9603
9562
  map.clear();
9604
9563
  for (const [k, v] of Object.entries(raw)) map.set(k, v);
@@ -9642,10 +9601,10 @@ function createAppNameMapProvider(opts) {
9642
9601
  logger.warn("[app-name-map] refresh succeeded but got 0 entries");
9643
9602
  return;
9644
9603
  }
9645
- const dir = (0, import_node_path18.join)(stateDir, "plugins", PLUGIN_STATE_DIR);
9646
- (0, import_node_fs22.mkdirSync)(dir, { recursive: true });
9604
+ const dir = (0, import_node_path17.join)(stateDir, "plugins", PLUGIN_STATE_DIR);
9605
+ (0, import_node_fs21.mkdirSync)(dir, { recursive: true });
9647
9606
  const cachePath = getCachePath(stateDir);
9648
- (0, import_node_fs22.writeFileSync)(cachePath, JSON.stringify(Object.fromEntries(map), null, 2), "utf-8");
9607
+ (0, import_node_fs21.writeFileSync)(cachePath, JSON.stringify(Object.fromEntries(map), null, 2), "utf-8");
9649
9608
  logger.info(`[app-name-map] refreshed ${map.size} entries from server and saved: ${cachePath}`);
9650
9609
  } catch (e) {
9651
9610
  const message = e instanceof Error ? e.message : String(e);
@@ -9689,19 +9648,19 @@ function createAppNameMapProvider(opts) {
9689
9648
  }
9690
9649
 
9691
9650
  // src/notification/storage.ts
9692
- var import_node_fs23 = require("fs");
9651
+ var import_node_fs22 = require("fs");
9693
9652
  var import_node_crypto2 = require("crypto");
9694
- var import_node_path19 = require("path");
9653
+ var import_node_path18 = require("path");
9695
9654
  var NOTIFICATION_DIR_NAME = "notifications";
9696
9655
  var ID_INDEX_DIR_NAME = ".ids";
9697
9656
  var CONTENT_KEY_INDEX_DIR_NAME = ".keys";
9698
9657
  function getStateFallbackNotificationDir(stateDir) {
9699
- return (0, import_node_path19.join)(stateDir, "plugins", "phone-notifications", NOTIFICATION_DIR_NAME);
9658
+ return (0, import_node_path18.join)(stateDir, "plugins", "phone-notifications", NOTIFICATION_DIR_NAME);
9700
9659
  }
9701
9660
  function ensureWritableDirectory(dir) {
9702
9661
  try {
9703
- (0, import_node_fs23.mkdirSync)(dir, { recursive: true });
9704
- (0, import_node_fs23.accessSync)(dir, import_node_fs23.constants.R_OK | import_node_fs23.constants.W_OK);
9662
+ (0, import_node_fs22.mkdirSync)(dir, { recursive: true });
9663
+ (0, import_node_fs22.accessSync)(dir, import_node_fs22.constants.R_OK | import_node_fs22.constants.W_OK);
9705
9664
  return true;
9706
9665
  } catch {
9707
9666
  return false;
@@ -9714,7 +9673,7 @@ function resolveNotificationStorageDir(ctx, logger) {
9714
9673
  return stateNotifDir;
9715
9674
  }
9716
9675
  if (ctx.workspaceDir) {
9717
- const workspaceDir = (0, import_node_path19.join)(ctx.workspaceDir, NOTIFICATION_DIR_NAME);
9676
+ const workspaceDir = (0, import_node_path18.join)(ctx.workspaceDir, NOTIFICATION_DIR_NAME);
9718
9677
  if (ensureWritableDirectory(workspaceDir)) {
9719
9678
  logger.warn(
9720
9679
  `stateDir \u4E0D\u53EF\u7528\uFF0C\u901A\u77E5\u5DF2\u56DE\u9000\u5230 workspace \u8DEF\u5F84: ${workspaceDir}`
@@ -9729,8 +9688,8 @@ var NotificationStorage = class {
9729
9688
  this.config = config;
9730
9689
  this.logger = logger;
9731
9690
  this.dir = dir;
9732
- this.idIndexDir = (0, import_node_path19.join)(dir, ID_INDEX_DIR_NAME);
9733
- this.contentKeyIndexDir = (0, import_node_path19.join)(dir, CONTENT_KEY_INDEX_DIR_NAME);
9691
+ this.idIndexDir = (0, import_node_path18.join)(dir, ID_INDEX_DIR_NAME);
9692
+ this.contentKeyIndexDir = (0, import_node_path18.join)(dir, CONTENT_KEY_INDEX_DIR_NAME);
9734
9693
  this.resolveDisplayName = resolveDisplayName;
9735
9694
  }
9736
9695
  dir;
@@ -9741,10 +9700,10 @@ var NotificationStorage = class {
9741
9700
  dateWriteChains = /* @__PURE__ */ new Map();
9742
9701
  resolveDisplayName;
9743
9702
  async init() {
9744
- (0, import_node_fs23.mkdirSync)(this.dir, { recursive: true });
9745
- (0, import_node_fs23.mkdirSync)(this.idIndexDir, { recursive: true });
9746
- (0, import_node_fs23.rmSync)(this.contentKeyIndexDir, { recursive: true, force: true });
9747
- (0, import_node_fs23.mkdirSync)(this.contentKeyIndexDir, { recursive: true });
9703
+ (0, import_node_fs22.mkdirSync)(this.dir, { recursive: true });
9704
+ (0, import_node_fs22.mkdirSync)(this.idIndexDir, { recursive: true });
9705
+ (0, import_node_fs22.rmSync)(this.contentKeyIndexDir, { recursive: true, force: true });
9706
+ (0, import_node_fs22.mkdirSync)(this.contentKeyIndexDir, { recursive: true });
9748
9707
  }
9749
9708
  async ingest(items) {
9750
9709
  const result = {
@@ -9783,7 +9742,7 @@ var NotificationStorage = class {
9783
9742
  return { kind: "invalid" };
9784
9743
  }
9785
9744
  const dateKey = this.formatDate(ts);
9786
- const filePath = (0, import_node_path19.join)(this.dir, `${dateKey}.json`);
9745
+ const filePath = (0, import_node_path18.join)(this.dir, `${dateKey}.json`);
9787
9746
  const normalizedId = typeof n.id === "string" ? n.id.trim() : "";
9788
9747
  const entry = this.buildStoredNotification(n);
9789
9748
  return this.withDateWriteLock(dateKey, async () => {
@@ -9800,7 +9759,7 @@ var NotificationStorage = class {
9800
9759
  };
9801
9760
  const arr = this.readStoredNotifications(filePath);
9802
9761
  arr.push(storedEntry);
9803
- (0, import_node_fs23.writeFileSync)(filePath, JSON.stringify(arr, null, 2), "utf-8");
9762
+ (0, import_node_fs22.writeFileSync)(filePath, JSON.stringify(arr, null, 2), "utf-8");
9804
9763
  if (normalizedId) {
9805
9764
  this.recordNotificationId(dateKey, normalizedId);
9806
9765
  }
@@ -9837,7 +9796,7 @@ var NotificationStorage = class {
9837
9796
  return `${year}-${month}-${day}`;
9838
9797
  }
9839
9798
  getIdIndexPath(dateKey) {
9840
- return (0, import_node_path19.join)(this.idIndexDir, `${dateKey}.ids`);
9799
+ return (0, import_node_path18.join)(this.idIndexDir, `${dateKey}.ids`);
9841
9800
  }
9842
9801
  getIdSet(dateKey) {
9843
9802
  const cached = this.idCache.get(dateKey);
@@ -9846,8 +9805,8 @@ var NotificationStorage = class {
9846
9805
  }
9847
9806
  const idPath = this.getIdIndexPath(dateKey);
9848
9807
  const ids = /* @__PURE__ */ new Set();
9849
- if ((0, import_node_fs23.existsSync)(idPath)) {
9850
- const lines = (0, import_node_fs23.readFileSync)(idPath, "utf-8").split(/\r?\n/);
9808
+ if ((0, import_node_fs22.existsSync)(idPath)) {
9809
+ const lines = (0, import_node_fs22.readFileSync)(idPath, "utf-8").split(/\r?\n/);
9851
9810
  for (const line of lines) {
9852
9811
  const id = line.trim();
9853
9812
  if (id) {
@@ -9862,7 +9821,7 @@ var NotificationStorage = class {
9862
9821
  return this.getIdSet(dateKey).has(id);
9863
9822
  }
9864
9823
  getContentKeyIndexPath(dateKey) {
9865
- return (0, import_node_path19.join)(this.contentKeyIndexDir, `${dateKey}.keys`);
9824
+ return (0, import_node_path18.join)(this.contentKeyIndexDir, `${dateKey}.keys`);
9866
9825
  }
9867
9826
  getContentKeySet(dateKey, filePath) {
9868
9827
  const cached = this.contentKeyCache.get(dateKey);
@@ -9871,16 +9830,16 @@ var NotificationStorage = class {
9871
9830
  }
9872
9831
  const keyPath = this.getContentKeyIndexPath(dateKey);
9873
9832
  const keys = /* @__PURE__ */ new Set();
9874
- if ((0, import_node_fs23.existsSync)(filePath)) {
9833
+ if ((0, import_node_fs22.existsSync)(filePath)) {
9875
9834
  for (const item of this.readStoredNotifications(filePath)) {
9876
9835
  keys.add(this.buildNotificationContentKey(item));
9877
9836
  }
9878
9837
  }
9879
9838
  if (keys.size > 0) {
9880
- (0, import_node_fs23.writeFileSync)(keyPath, `${Array.from(keys).join("\n")}
9839
+ (0, import_node_fs22.writeFileSync)(keyPath, `${Array.from(keys).join("\n")}
9881
9840
  `, "utf-8");
9882
- } else if ((0, import_node_fs23.existsSync)(keyPath)) {
9883
- (0, import_node_fs23.rmSync)(keyPath, { force: true });
9841
+ } else if ((0, import_node_fs22.existsSync)(keyPath)) {
9842
+ (0, import_node_fs22.rmSync)(keyPath, { force: true });
9884
9843
  }
9885
9844
  this.contentKeyCache.set(dateKey, keys);
9886
9845
  return keys;
@@ -9895,7 +9854,7 @@ var NotificationStorage = class {
9895
9854
  if (ids.has(id)) {
9896
9855
  return;
9897
9856
  }
9898
- (0, import_node_fs23.appendFileSync)(this.getIdIndexPath(dateKey), `${id}
9857
+ (0, import_node_fs22.appendFileSync)(this.getIdIndexPath(dateKey), `${id}
9899
9858
  `, "utf-8");
9900
9859
  ids.add(id);
9901
9860
  }
@@ -9905,7 +9864,7 @@ var NotificationStorage = class {
9905
9864
  if (keys.has(key)) {
9906
9865
  return;
9907
9866
  }
9908
- (0, import_node_fs23.appendFileSync)(this.getContentKeyIndexPath(dateKey), `${key}
9867
+ (0, import_node_fs22.appendFileSync)(this.getContentKeyIndexPath(dateKey), `${key}
9909
9868
  `, "utf-8");
9910
9869
  keys.add(key);
9911
9870
  }
@@ -9913,11 +9872,11 @@ var NotificationStorage = class {
9913
9872
  return (0, import_node_crypto2.createHash)("sha256").update(entry.appName).update("").update(entry.title).update("").update(entry.content).update("").update(entry.timestamp).digest("hex");
9914
9873
  }
9915
9874
  readStoredNotifications(filePath) {
9916
- if (!(0, import_node_fs23.existsSync)(filePath)) {
9875
+ if (!(0, import_node_fs22.existsSync)(filePath)) {
9917
9876
  return [];
9918
9877
  }
9919
9878
  try {
9920
- const parsed = JSON.parse((0, import_node_fs23.readFileSync)(filePath, "utf-8"));
9879
+ const parsed = JSON.parse((0, import_node_fs22.readFileSync)(filePath, "utf-8"));
9921
9880
  return Array.isArray(parsed) ? parsed : [];
9922
9881
  } catch {
9923
9882
  return [];
@@ -9957,14 +9916,14 @@ var NotificationStorage = class {
9957
9916
  const dateFilePattern = /^(\d{4}-\d{2}-\d{2})\.(json|md)$/;
9958
9917
  const dateDirPattern = /^\d{4}-\d{2}-\d{2}$/;
9959
9918
  try {
9960
- for (const entry of (0, import_node_fs23.readdirSync)(this.dir, { withFileTypes: true })) {
9919
+ for (const entry of (0, import_node_fs22.readdirSync)(this.dir, { withFileTypes: true })) {
9961
9920
  if (entry.isFile()) {
9962
9921
  const match = dateFilePattern.exec(entry.name);
9963
9922
  if (match && match[1] < cutoffDate) {
9964
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, entry.name), { force: true });
9923
+ (0, import_node_fs22.rmSync)((0, import_node_path18.join)(this.dir, entry.name), { force: true });
9965
9924
  }
9966
9925
  } else if (entry.isDirectory() && dateDirPattern.test(entry.name) && entry.name < cutoffDate) {
9967
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, entry.name), { recursive: true, force: true });
9926
+ (0, import_node_fs22.rmSync)((0, import_node_path18.join)(this.dir, entry.name), { recursive: true, force: true });
9968
9927
  }
9969
9928
  }
9970
9929
  } catch {
@@ -9973,11 +9932,11 @@ var NotificationStorage = class {
9973
9932
  /** Remove expired .ids index files */
9974
9933
  pruneIdIndex(cutoffDate) {
9975
9934
  try {
9976
- for (const entry of (0, import_node_fs23.readdirSync)(this.idIndexDir, { withFileTypes: true })) {
9935
+ for (const entry of (0, import_node_fs22.readdirSync)(this.idIndexDir, { withFileTypes: true })) {
9977
9936
  if (!entry.isFile()) continue;
9978
9937
  const match = /^(\d{4}-\d{2}-\d{2})\.ids$/.exec(entry.name);
9979
9938
  if (match && match[1] < cutoffDate) {
9980
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.idIndexDir, entry.name), { force: true });
9939
+ (0, import_node_fs22.rmSync)((0, import_node_path18.join)(this.idIndexDir, entry.name), { force: true });
9981
9940
  this.idCache.delete(match[1]);
9982
9941
  }
9983
9942
  }
@@ -9986,11 +9945,11 @@ var NotificationStorage = class {
9986
9945
  }
9987
9946
  pruneContentKeyIndex(cutoffDate) {
9988
9947
  try {
9989
- for (const entry of (0, import_node_fs23.readdirSync)(this.contentKeyIndexDir, { withFileTypes: true })) {
9948
+ for (const entry of (0, import_node_fs22.readdirSync)(this.contentKeyIndexDir, { withFileTypes: true })) {
9990
9949
  if (!entry.isFile()) continue;
9991
9950
  const match = /^(\d{4}-\d{2}-\d{2})\.keys$/.exec(entry.name);
9992
9951
  if (match && match[1] < cutoffDate) {
9993
- (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.contentKeyIndexDir, entry.name), { force: true });
9952
+ (0, import_node_fs22.rmSync)((0, import_node_path18.join)(this.contentKeyIndexDir, entry.name), { force: true });
9994
9953
  this.contentKeyCache.delete(match[1]);
9995
9954
  }
9996
9955
  }
@@ -10005,8 +9964,8 @@ var NotificationStorage = class {
10005
9964
  };
10006
9965
 
10007
9966
  // src/recording/storage.ts
10008
- var import_node_fs24 = require("fs");
10009
- var import_node_path20 = require("path");
9967
+ var import_node_fs23 = require("fs");
9968
+ var import_node_path19 = require("path");
10010
9969
 
10011
9970
  // src/recording/state-machine.ts
10012
9971
  var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
@@ -10067,7 +10026,7 @@ function stripMarkdownFence(markdown) {
10067
10026
  }
10068
10027
  function deriveTitleFromTranscriptPath(transcriptFile, recordingId) {
10069
10028
  if (!transcriptFile) return void 0;
10070
- const name = (0, import_node_path20.basename)(transcriptFile, ".md");
10029
+ const name = (0, import_node_path19.basename)(transcriptFile, ".md");
10071
10030
  const prefix = `${recordingId}_`;
10072
10031
  if (name.startsWith(prefix)) {
10073
10032
  const derived = name.slice(prefix.length).trim();
@@ -10095,22 +10054,22 @@ function extractTranscriptContent(markdown) {
10095
10054
  return lines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
10096
10055
  }
10097
10056
  function resolveRecordingStorageDir(ctx, logger) {
10098
- const stateRecDir = (0, import_node_path20.join)(
10057
+ const stateRecDir = (0, import_node_path19.join)(
10099
10058
  ctx.stateDir,
10100
10059
  "plugins",
10101
10060
  "phone-notifications",
10102
10061
  RECORDINGS_DIR
10103
10062
  );
10104
10063
  try {
10105
- (0, import_node_fs24.mkdirSync)(stateRecDir, { recursive: true });
10064
+ (0, import_node_fs23.mkdirSync)(stateRecDir, { recursive: true });
10106
10065
  logger.info(`\u5F55\u97F3\u5C06\u5199\u5165 stateDir \u8DEF\u5F84: ${stateRecDir}`);
10107
10066
  return stateRecDir;
10108
10067
  } catch {
10109
10068
  }
10110
10069
  if (ctx.workspaceDir) {
10111
- const wsRecDir = (0, import_node_path20.join)(ctx.workspaceDir, RECORDINGS_DIR);
10070
+ const wsRecDir = (0, import_node_path19.join)(ctx.workspaceDir, RECORDINGS_DIR);
10112
10071
  try {
10113
- (0, import_node_fs24.mkdirSync)(wsRecDir, { recursive: true });
10072
+ (0, import_node_fs23.mkdirSync)(wsRecDir, { recursive: true });
10114
10073
  logger.warn(`stateDir \u4E0D\u53EF\u7528\uFF0C\u5F55\u97F3\u5DF2\u56DE\u9000\u5230 workspace \u8DEF\u5F84: ${wsRecDir}`);
10115
10074
  return wsRecDir;
10116
10075
  } catch {
@@ -10122,11 +10081,11 @@ var RecordingStorage = class {
10122
10081
  constructor(dir, logger) {
10123
10082
  this.logger = logger;
10124
10083
  this.dir = dir;
10125
- this.audioDir = (0, import_node_path20.join)(dir, AUDIO_DIR);
10126
- this.transcriptDataDir = (0, import_node_path20.join)(dir, TRANSCRIPT_DATA_DIR);
10127
- this.transcriptsDir = (0, import_node_path20.join)(dir, TRANSCRIPTS_DIR);
10128
- this.summariesDir = (0, import_node_path20.join)(dir, SUMMARIES_DIR);
10129
- this.indexPath = (0, import_node_path20.join)(dir, INDEX_FILE);
10084
+ this.audioDir = (0, import_node_path19.join)(dir, AUDIO_DIR);
10085
+ this.transcriptDataDir = (0, import_node_path19.join)(dir, TRANSCRIPT_DATA_DIR);
10086
+ this.transcriptsDir = (0, import_node_path19.join)(dir, TRANSCRIPTS_DIR);
10087
+ this.summariesDir = (0, import_node_path19.join)(dir, SUMMARIES_DIR);
10088
+ this.indexPath = (0, import_node_path19.join)(dir, INDEX_FILE);
10130
10089
  }
10131
10090
  dir;
10132
10091
  audioDir;
@@ -10137,10 +10096,10 @@ var RecordingStorage = class {
10137
10096
  index = { recordings: [] };
10138
10097
  /** 初始化目录结构并加载索引 */
10139
10098
  async init() {
10140
- (0, import_node_fs24.mkdirSync)(this.audioDir, { recursive: true });
10141
- (0, import_node_fs24.mkdirSync)(this.transcriptDataDir, { recursive: true });
10142
- (0, import_node_fs24.mkdirSync)(this.transcriptsDir, { recursive: true });
10143
- (0, import_node_fs24.mkdirSync)(this.summariesDir, { recursive: true });
10099
+ (0, import_node_fs23.mkdirSync)(this.audioDir, { recursive: true });
10100
+ (0, import_node_fs23.mkdirSync)(this.transcriptDataDir, { recursive: true });
10101
+ (0, import_node_fs23.mkdirSync)(this.transcriptsDir, { recursive: true });
10102
+ (0, import_node_fs23.mkdirSync)(this.summariesDir, { recursive: true });
10144
10103
  this.loadIndex();
10145
10104
  this.logger.info(
10146
10105
  `\u5F55\u97F3\u5B58\u50A8\u5DF2\u521D\u59CB\u5316: ${this.dir}\uFF08\u5171 ${this.index.recordings.length} \u6761\u8BB0\u5F55\uFF09`
@@ -10184,13 +10143,13 @@ var RecordingStorage = class {
10184
10143
  return id;
10185
10144
  }
10186
10145
  if (existing.transcriptDataFile) {
10187
- (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, existing.transcriptDataFile), { force: true });
10146
+ (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, existing.transcriptDataFile), { force: true });
10188
10147
  }
10189
10148
  if (existing.transcriptFile) {
10190
- (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, existing.transcriptFile), { force: true });
10149
+ (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, existing.transcriptFile), { force: true });
10191
10150
  }
10192
10151
  if (existing.summaryFile) {
10193
- (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, existing.summaryFile), { force: true });
10152
+ (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, existing.summaryFile), { force: true });
10194
10153
  }
10195
10154
  existing.metadata = metadata;
10196
10155
  existing.status = "syncing_openclaw";
@@ -10258,7 +10217,7 @@ var RecordingStorage = class {
10258
10217
  if (!entry) return;
10259
10218
  const nextTranscriptDataFile = `${TRANSCRIPT_DATA_DIR}/${filename}`;
10260
10219
  if (entry.transcriptDataFile && entry.transcriptDataFile !== nextTranscriptDataFile) {
10261
- (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, entry.transcriptDataFile), { force: true });
10220
+ (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, entry.transcriptDataFile), { force: true });
10262
10221
  }
10263
10222
  entry.transcriptDataFile = nextTranscriptDataFile;
10264
10223
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -10272,7 +10231,7 @@ var RecordingStorage = class {
10272
10231
  if (!entry) return;
10273
10232
  const nextTranscriptFile = `${TRANSCRIPTS_DIR}/${filename}`;
10274
10233
  if (entry.transcriptFile && entry.transcriptFile !== nextTranscriptFile) {
10275
- (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, entry.transcriptFile), { force: true });
10234
+ (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, entry.transcriptFile), { force: true });
10276
10235
  }
10277
10236
  entry.transcriptFile = nextTranscriptFile;
10278
10237
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -10286,7 +10245,7 @@ var RecordingStorage = class {
10286
10245
  if (!entry) return;
10287
10246
  const nextSummaryFile = `${SUMMARIES_DIR}/${filename}`;
10288
10247
  if (entry.summaryFile && entry.summaryFile !== nextSummaryFile) {
10289
- (0, import_node_fs24.rmSync)((0, import_node_path20.join)(this.dir, entry.summaryFile), { force: true });
10248
+ (0, import_node_fs23.rmSync)((0, import_node_path19.join)(this.dir, entry.summaryFile), { force: true });
10290
10249
  }
10291
10250
  entry.summaryFile = nextSummaryFile;
10292
10251
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -10384,24 +10343,24 @@ var RecordingStorage = class {
10384
10343
  const entry = this.findById(recordingId);
10385
10344
  if (!entry) return false;
10386
10345
  if (entry.audioFile) {
10387
- const audioPath = (0, import_node_path20.join)(this.dir, entry.audioFile);
10388
- (0, import_node_fs24.rmSync)(audioPath, { force: true });
10346
+ const audioPath = (0, import_node_path19.join)(this.dir, entry.audioFile);
10347
+ (0, import_node_fs23.rmSync)(audioPath, { force: true });
10389
10348
  }
10390
10349
  if (entry.srtFile) {
10391
- const srtPath = (0, import_node_path20.join)(this.dir, entry.srtFile);
10392
- (0, import_node_fs24.rmSync)(srtPath, { force: true });
10350
+ const srtPath = (0, import_node_path19.join)(this.dir, entry.srtFile);
10351
+ (0, import_node_fs23.rmSync)(srtPath, { force: true });
10393
10352
  }
10394
10353
  if (entry.transcriptDataFile) {
10395
- const transcriptDataPath = (0, import_node_path20.join)(this.dir, entry.transcriptDataFile);
10396
- (0, import_node_fs24.rmSync)(transcriptDataPath, { force: true });
10354
+ const transcriptDataPath = (0, import_node_path19.join)(this.dir, entry.transcriptDataFile);
10355
+ (0, import_node_fs23.rmSync)(transcriptDataPath, { force: true });
10397
10356
  }
10398
10357
  if (entry.transcriptFile) {
10399
- const transcriptPath = (0, import_node_path20.join)(this.dir, entry.transcriptFile);
10400
- (0, import_node_fs24.rmSync)(transcriptPath, { force: true });
10358
+ const transcriptPath = (0, import_node_path19.join)(this.dir, entry.transcriptFile);
10359
+ (0, import_node_fs23.rmSync)(transcriptPath, { force: true });
10401
10360
  }
10402
10361
  if (entry.summaryFile) {
10403
- const summaryPath = (0, import_node_path20.join)(this.dir, entry.summaryFile);
10404
- (0, import_node_fs24.rmSync)(summaryPath, { force: true });
10362
+ const summaryPath = (0, import_node_path19.join)(this.dir, entry.summaryFile);
10363
+ (0, import_node_fs23.rmSync)(summaryPath, { force: true });
10405
10364
  }
10406
10365
  if (opts?.localOnly) {
10407
10366
  entry.audioFile = void 0;
@@ -10459,34 +10418,34 @@ var RecordingStorage = class {
10459
10418
  * 获取音频文件的绝对路径。ossUrl 用于推断文件扩展名
10460
10419
  */
10461
10420
  getAudioFilePath(recordingId, ossUrl) {
10462
- return (0, import_node_path20.join)(this.audioDir, this.buildAudioFilename(recordingId, ossUrl));
10421
+ return (0, import_node_path19.join)(this.audioDir, this.buildAudioFilename(recordingId, ossUrl));
10463
10422
  }
10464
10423
  /**
10465
10424
  * 获取打点文件的绝对路径
10466
10425
  */
10467
10426
  getSrtFilePath(recordingId) {
10468
- return (0, import_node_path20.join)(this.audioDir, this.buildSrtFilename(recordingId));
10427
+ return (0, import_node_path19.join)(this.audioDir, this.buildSrtFilename(recordingId));
10469
10428
  }
10470
10429
  /**
10471
10430
  * 获取转写 JSON 文件的绝对路径
10472
10431
  */
10473
10432
  getTranscriptDataFilePath(recordingId) {
10474
- return (0, import_node_path20.join)(this.transcriptDataDir, this.buildTranscriptDataFilename(recordingId));
10433
+ return (0, import_node_path19.join)(this.transcriptDataDir, this.buildTranscriptDataFilename(recordingId));
10475
10434
  }
10476
10435
  /**
10477
10436
  * 获取摘要文件的绝对路径
10478
10437
  */
10479
10438
  getSummaryFilePath(recordingId) {
10480
- return (0, import_node_path20.join)(this.summariesDir, this.buildSummaryFilename(recordingId));
10439
+ return (0, import_node_path19.join)(this.summariesDir, this.buildSummaryFilename(recordingId));
10481
10440
  }
10482
10441
  // ─── Persistence ───
10483
10442
  loadIndex() {
10484
- if (!(0, import_node_fs24.existsSync)(this.indexPath)) {
10443
+ if (!(0, import_node_fs23.existsSync)(this.indexPath)) {
10485
10444
  this.index = { recordings: [] };
10486
10445
  return;
10487
10446
  }
10488
10447
  try {
10489
- const raw = JSON.parse((0, import_node_fs24.readFileSync)(this.indexPath, "utf-8"));
10448
+ const raw = JSON.parse((0, import_node_fs23.readFileSync)(this.indexPath, "utf-8"));
10490
10449
  if (raw && Array.isArray(raw.recordings)) {
10491
10450
  let needsRewrite = false;
10492
10451
  const normalized = raw.recordings.filter((entry) => entry && typeof entry === "object").map((entry) => {
@@ -10524,8 +10483,8 @@ var RecordingStorage = class {
10524
10483
  segments: []
10525
10484
  });
10526
10485
  const transcriptDataFilename = this.buildTranscriptDataFilename(compacted.id);
10527
- (0, import_node_fs24.writeFileSync)(
10528
- (0, import_node_path20.join)(this.transcriptDataDir, transcriptDataFilename),
10486
+ (0, import_node_fs23.writeFileSync)(
10487
+ (0, import_node_path19.join)(this.transcriptDataDir, transcriptDataFilename),
10529
10488
  JSON.stringify(transcriptDoc, null, 2),
10530
10489
  "utf-8"
10531
10490
  );
@@ -10537,8 +10496,8 @@ var RecordingStorage = class {
10537
10496
  compacted.summaryFile = entry.summaryFile;
10538
10497
  } else if (typeof entry.summary === "string" && entry.summary.trim()) {
10539
10498
  const summaryFilename = this.buildSummaryFilename(entry.id);
10540
- (0, import_node_fs24.writeFileSync)(
10541
- (0, import_node_path20.join)(this.summariesDir, summaryFilename),
10499
+ (0, import_node_fs23.writeFileSync)(
10500
+ (0, import_node_path19.join)(this.summariesDir, summaryFilename),
10542
10501
  entry.summary.trim(),
10543
10502
  "utf-8"
10544
10503
  );
@@ -10548,8 +10507,8 @@ var RecordingStorage = class {
10548
10507
  const summaryFromDocument = extractTranscriptSummaryFromDocument(transcriptDoc);
10549
10508
  if (summaryFromDocument) {
10550
10509
  const summaryFilename = this.buildSummaryFilename(entry.id);
10551
- (0, import_node_fs24.writeFileSync)(
10552
- (0, import_node_path20.join)(this.summariesDir, summaryFilename),
10510
+ (0, import_node_fs23.writeFileSync)(
10511
+ (0, import_node_path19.join)(this.summariesDir, summaryFilename),
10553
10512
  summaryFromDocument,
10554
10513
  "utf-8"
10555
10514
  );
@@ -10589,7 +10548,7 @@ var RecordingStorage = class {
10589
10548
  }
10590
10549
  readRelativeTextFile(relativePath) {
10591
10550
  try {
10592
- return (0, import_node_fs24.readFileSync)((0, import_node_path20.join)(this.dir, relativePath), "utf-8");
10551
+ return (0, import_node_fs23.readFileSync)((0, import_node_path19.join)(this.dir, relativePath), "utf-8");
10593
10552
  } catch {
10594
10553
  return void 0;
10595
10554
  }
@@ -10602,7 +10561,7 @@ var RecordingStorage = class {
10602
10561
  return parseTranscriptDocument(raw);
10603
10562
  }
10604
10563
  saveIndex() {
10605
- (0, import_node_fs24.writeFileSync)(
10564
+ (0, import_node_fs23.writeFileSync)(
10606
10565
  this.indexPath,
10607
10566
  JSON.stringify(this.index, null, 2),
10608
10567
  "utf-8"
@@ -10616,8 +10575,8 @@ var RecordingStorage = class {
10616
10575
  init_transcript_document();
10617
10576
 
10618
10577
  // src/recording/downloader.ts
10619
- var import_node_fs25 = require("fs");
10620
- var import_node_path21 = require("path");
10578
+ var import_node_fs24 = require("fs");
10579
+ var import_node_path20 = require("path");
10621
10580
  var import_promises2 = require("stream/promises");
10622
10581
  var import_node_stream = require("stream");
10623
10582
  var DEFAULT_TIMEOUT_MS2 = 5 * 60 * 1e3;
@@ -10627,7 +10586,7 @@ async function downloadFile(url, destPath, logger, options) {
10627
10586
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
10628
10587
  const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
10629
10588
  const retryBackoffMs = options?.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS;
10630
- (0, import_node_fs25.mkdirSync)((0, import_node_path21.dirname)(destPath), { recursive: true });
10589
+ (0, import_node_fs24.mkdirSync)((0, import_node_path20.dirname)(destPath), { recursive: true });
10631
10590
  let lastError;
10632
10591
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
10633
10592
  const startMs = Date.now();
@@ -10645,11 +10604,11 @@ async function downloadFile(url, destPath, logger, options) {
10645
10604
  if (!res.body) {
10646
10605
  throw new Error("\u54CD\u5E94\u4F53\u4E3A\u7A7A");
10647
10606
  }
10648
- const writeStream = (0, import_node_fs25.createWriteStream)(destPath);
10607
+ const writeStream = (0, import_node_fs24.createWriteStream)(destPath);
10649
10608
  const readable = import_node_stream.Readable.fromWeb(res.body);
10650
10609
  await (0, import_promises2.pipeline)(readable, writeStream);
10651
10610
  const elapsed = Date.now() - startMs;
10652
- const fileSize = (0, import_node_fs25.existsSync)(destPath) ? (0, import_node_fs25.statSync)(destPath).size : 0;
10611
+ const fileSize = (0, import_node_fs24.existsSync)(destPath) ? (0, import_node_fs24.statSync)(destPath).size : 0;
10653
10612
  logger.info(
10654
10613
  `[downloader] \u4E0B\u8F7D\u5B8C\u6210: ${destPath} (${formatBytes(fileSize)}, ${elapsed}ms)`
10655
10614
  );
@@ -10660,7 +10619,7 @@ async function downloadFile(url, destPath, logger, options) {
10660
10619
  } catch (err2) {
10661
10620
  lastError = err2?.message ?? String(err2);
10662
10621
  try {
10663
- if ((0, import_node_fs25.existsSync)(destPath)) (0, import_node_fs25.unlinkSync)(destPath);
10622
+ if ((0, import_node_fs24.existsSync)(destPath)) (0, import_node_fs24.unlinkSync)(destPath);
10664
10623
  } catch {
10665
10624
  }
10666
10625
  const isAbort = err2?.name === "AbortError";
@@ -10898,13 +10857,13 @@ async function triggerTranscription(recordingId, storage, asrConfig, logger, opt
10898
10857
  }
10899
10858
 
10900
10859
  // src/tunnel/service.ts
10901
- var import_node_fs30 = require("fs");
10902
- var import_node_path26 = require("path");
10860
+ var import_node_fs29 = require("fs");
10861
+ var import_node_path25 = require("path");
10903
10862
  init_credentials();
10904
10863
 
10905
10864
  // src/tunnel/relay-client.ts
10906
- var import_node_fs28 = require("fs");
10907
- var import_node_path24 = require("path");
10865
+ var import_node_fs27 = require("fs");
10866
+ var import_node_path23 = require("path");
10908
10867
 
10909
10868
  // node_modules/.pnpm/ws@8.19.0/node_modules/ws/wrapper.mjs
10910
10869
  var import_stream = __toESM(require_stream(), 1);
@@ -10948,8 +10907,8 @@ var RelayClient = class {
10948
10907
  lastDisconnectReason
10949
10908
  };
10950
10909
  try {
10951
- (0, import_node_fs28.mkdirSync)((0, import_node_path24.dirname)(this.opts.statusFilePath), { recursive: true });
10952
- (0, import_node_fs28.writeFileSync)(this.opts.statusFilePath, JSON.stringify(info, null, 2));
10910
+ (0, import_node_fs27.mkdirSync)((0, import_node_path23.dirname)(this.opts.statusFilePath), { recursive: true });
10911
+ (0, import_node_fs27.writeFileSync)(this.opts.statusFilePath, JSON.stringify(info, null, 2));
10953
10912
  } catch {
10954
10913
  }
10955
10914
  }
@@ -11331,8 +11290,8 @@ init_host();
11331
11290
 
11332
11291
  // src/tunnel/device-identity.ts
11333
11292
  var import_node_crypto3 = __toESM(require("crypto"), 1);
11334
- var import_node_fs29 = __toESM(require("fs"), 1);
11335
- var import_node_path25 = __toESM(require("path"), 1);
11293
+ var import_node_fs28 = __toESM(require("fs"), 1);
11294
+ var import_node_path24 = __toESM(require("path"), 1);
11336
11295
  init_host();
11337
11296
  var ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
11338
11297
  function base64UrlEncode(buf) {
@@ -11377,10 +11336,10 @@ function resolveClientStateDir(stateDir) {
11377
11336
  return stateDir ?? resolveStateDir();
11378
11337
  }
11379
11338
  function ensureDir(filePath) {
11380
- import_node_fs29.default.mkdirSync(import_node_path25.default.dirname(filePath), { recursive: true });
11339
+ import_node_fs28.default.mkdirSync(import_node_path24.default.dirname(filePath), { recursive: true });
11381
11340
  }
11382
11341
  function resolveIdentityPath(stateDir) {
11383
- return import_node_path25.default.join(stateDir, "identity", "device.json");
11342
+ return import_node_path24.default.join(stateDir, "identity", "device.json");
11384
11343
  }
11385
11344
  function normalizeDeviceAuthRole(role) {
11386
11345
  return role.trim();
@@ -11396,12 +11355,12 @@ function normalizeDeviceAuthScopes(scopes) {
11396
11355
  return [...out].sort();
11397
11356
  }
11398
11357
  function resolveDeviceAuthPath(stateDir) {
11399
- return import_node_path25.default.join(stateDir, "identity", "device-auth.json");
11358
+ return import_node_path24.default.join(stateDir, "identity", "device-auth.json");
11400
11359
  }
11401
11360
  function readDeviceAuthStore(filePath) {
11402
11361
  try {
11403
- if (!import_node_fs29.default.existsSync(filePath)) return null;
11404
- const raw = import_node_fs29.default.readFileSync(filePath, "utf8");
11362
+ if (!import_node_fs28.default.existsSync(filePath)) return null;
11363
+ const raw = import_node_fs28.default.readFileSync(filePath, "utf8");
11405
11364
  const parsed = JSON.parse(raw);
11406
11365
  if (parsed?.version !== 1 || typeof parsed.deviceId !== "string") return null;
11407
11366
  if (!parsed.tokens || typeof parsed.tokens !== "object") return null;
@@ -11412,12 +11371,12 @@ function readDeviceAuthStore(filePath) {
11412
11371
  }
11413
11372
  function writeDeviceAuthStore(filePath, store) {
11414
11373
  ensureDir(filePath);
11415
- import_node_fs29.default.writeFileSync(filePath, `${JSON.stringify(store, null, 2)}
11374
+ import_node_fs28.default.writeFileSync(filePath, `${JSON.stringify(store, null, 2)}
11416
11375
  `, {
11417
11376
  mode: 384
11418
11377
  });
11419
11378
  try {
11420
- import_node_fs29.default.chmodSync(filePath, 384);
11379
+ import_node_fs28.default.chmodSync(filePath, 384);
11421
11380
  } catch {
11422
11381
  }
11423
11382
  }
@@ -11464,8 +11423,8 @@ function clearDeviceAuthToken(params) {
11464
11423
  function loadOrCreateDeviceIdentity(stateDir) {
11465
11424
  const filePath = resolveIdentityPath(stateDir);
11466
11425
  try {
11467
- if (import_node_fs29.default.existsSync(filePath)) {
11468
- const raw = import_node_fs29.default.readFileSync(filePath, "utf8");
11426
+ if (import_node_fs28.default.existsSync(filePath)) {
11427
+ const raw = import_node_fs28.default.readFileSync(filePath, "utf8");
11469
11428
  const parsed = JSON.parse(raw);
11470
11429
  if (parsed?.version === 1 && typeof parsed.deviceId === "string" && typeof parsed.publicKeyPem === "string" && typeof parsed.privateKeyPem === "string") {
11471
11430
  const derivedId = fingerprintPublicKey(parsed.publicKeyPem);
@@ -11486,14 +11445,14 @@ function loadOrCreateDeviceIdentity(stateDir) {
11486
11445
  publicKeyPem,
11487
11446
  privateKeyPem
11488
11447
  };
11489
- import_node_fs29.default.mkdirSync(import_node_path25.default.dirname(filePath), { recursive: true });
11448
+ import_node_fs28.default.mkdirSync(import_node_path24.default.dirname(filePath), { recursive: true });
11490
11449
  const stored = {
11491
11450
  version: 1,
11492
11451
  ...identity,
11493
11452
  createdAtMs: Date.now()
11494
11453
  };
11495
11454
  ensureDir(filePath);
11496
- import_node_fs29.default.writeFileSync(filePath, `${JSON.stringify(stored, null, 2)}
11455
+ import_node_fs28.default.writeFileSync(filePath, `${JSON.stringify(stored, null, 2)}
11497
11456
  `, {
11498
11457
  mode: 384
11499
11458
  });
@@ -12265,7 +12224,7 @@ function createTunnelService(opts) {
12265
12224
  }
12266
12225
  function readLockOwner(filePath) {
12267
12226
  try {
12268
- const parsed = JSON.parse((0, import_node_fs30.readFileSync)(filePath, "utf-8"));
12227
+ const parsed = JSON.parse((0, import_node_fs29.readFileSync)(filePath, "utf-8"));
12269
12228
  return typeof parsed.pid === "number" ? parsed.pid : null;
12270
12229
  } catch {
12271
12230
  return null;
@@ -12278,23 +12237,23 @@ function createTunnelService(opts) {
12278
12237
  lockFd = null;
12279
12238
  if (fd !== null) {
12280
12239
  try {
12281
- (0, import_node_fs30.closeSync)(fd);
12240
+ (0, import_node_fs29.closeSync)(fd);
12282
12241
  } catch {
12283
12242
  }
12284
12243
  }
12285
12244
  if (filePath) {
12286
12245
  try {
12287
- (0, import_node_fs30.unlinkSync)(filePath);
12246
+ (0, import_node_fs29.unlinkSync)(filePath);
12288
12247
  } catch {
12289
12248
  }
12290
12249
  }
12291
12250
  }
12292
12251
  function acquireLock(filePath) {
12293
- (0, import_node_fs30.mkdirSync)((0, import_node_path26.dirname)(filePath), { recursive: true });
12252
+ (0, import_node_fs29.mkdirSync)((0, import_node_path25.dirname)(filePath), { recursive: true });
12294
12253
  for (let attempt = 0; attempt < 2; attempt++) {
12295
12254
  try {
12296
- const fd = (0, import_node_fs30.openSync)(filePath, "wx", 384);
12297
- (0, import_node_fs30.writeFileSync)(
12255
+ const fd = (0, import_node_fs29.openSync)(filePath, "wx", 384);
12256
+ (0, import_node_fs29.writeFileSync)(
12298
12257
  fd,
12299
12258
  JSON.stringify({
12300
12259
  pid: process.pid,
@@ -12318,7 +12277,7 @@ function createTunnelService(opts) {
12318
12277
  `Relay tunnel: removing stale local lock owned by dead pid=${ownerPid}`
12319
12278
  );
12320
12279
  try {
12321
- (0, import_node_fs30.unlinkSync)(filePath);
12280
+ (0, import_node_fs29.unlinkSync)(filePath);
12322
12281
  } catch {
12323
12282
  }
12324
12283
  continue;
@@ -12363,12 +12322,12 @@ function createTunnelService(opts) {
12363
12322
  return;
12364
12323
  }
12365
12324
  const { logger } = opts;
12366
- const baseStateDir = (0, import_node_path26.join)(ctx.stateDir, "plugins", "phone-notifications");
12325
+ const baseStateDir = (0, import_node_path25.join)(ctx.stateDir, "plugins", "phone-notifications");
12367
12326
  logger.info(
12368
12327
  `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})`
12369
12328
  );
12370
- const statusFilePath = (0, import_node_path26.join)(baseStateDir, "tunnel-status.json");
12371
- const lockPath = (0, import_node_path26.join)(baseStateDir, "relay-tunnel.lock");
12329
+ const statusFilePath = (0, import_node_path25.join)(baseStateDir, "tunnel-status.json");
12330
+ const lockPath = (0, import_node_path25.join)(baseStateDir, "relay-tunnel.lock");
12372
12331
  if (!acquireLock(lockPath)) {
12373
12332
  return;
12374
12333
  }
@@ -12508,7 +12467,7 @@ function readHostGatewayConfig(params) {
12508
12467
  let configData;
12509
12468
  if (configPath) {
12510
12469
  try {
12511
- configData = JSON.parse((0, import_node_fs31.readFileSync)(configPath, "utf-8"));
12470
+ configData = JSON.parse((0, import_node_fs30.readFileSync)(configPath, "utf-8"));
12512
12471
  } catch (err2) {
12513
12472
  if (err2?.code !== "ENOENT") {
12514
12473
  params.logger.warn(
@@ -13270,7 +13229,6 @@ var index_default = {
13270
13229
  recordingStorage = nextRecordingStorage;
13271
13230
  },
13272
13231
  onStorageReady() {
13273
- migrateLegacyLightRuleTasks(lightRuleCtx, logger);
13274
13232
  lightRuleRegistry.reload();
13275
13233
  }
13276
13234
  });