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