@yoooclaw/cli 0.1.3 → 0.1.5
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/bin.cjs +124 -131
- package/dist/bin.cjs.map +4 -5
- package/dist/index.cjs +124 -131
- package/dist/index.cjs.map +4 -5
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -4272,7 +4272,7 @@ function buildContext(flags) {
|
|
|
4272
4272
|
var import_node_fs3 = require("node:fs");
|
|
4273
4273
|
function readBuildInjectedVersion() {
|
|
4274
4274
|
if (false) {}
|
|
4275
|
-
const version = "0.1.
|
|
4275
|
+
const version = "0.1.5".trim();
|
|
4276
4276
|
return version || undefined;
|
|
4277
4277
|
}
|
|
4278
4278
|
function readVersionFromPackageJson() {
|
|
@@ -6928,96 +6928,20 @@ class RecordingStorage {
|
|
|
6928
6928
|
}
|
|
6929
6929
|
async close() {}
|
|
6930
6930
|
}
|
|
6931
|
-
// src/vendor/recording/downloader.ts
|
|
6932
|
-
var import_node_fs11 = require("node:fs");
|
|
6933
|
-
var import_node_path8 = require("node:path");
|
|
6934
|
-
var import_promises3 = require("node:stream/promises");
|
|
6935
|
-
var import_node_stream = require("node:stream");
|
|
6936
|
-
var DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
6937
|
-
var DEFAULT_MAX_RETRIES = 3;
|
|
6938
|
-
var DEFAULT_RETRY_BACKOFF_MS = 2000;
|
|
6939
|
-
async function downloadFile(url, destPath, logger, options) {
|
|
6940
|
-
const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
6941
|
-
const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
6942
|
-
const retryBackoffMs = options?.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS;
|
|
6943
|
-
import_node_fs11.mkdirSync(import_node_path8.dirname(destPath), { recursive: true });
|
|
6944
|
-
let lastError;
|
|
6945
|
-
for (let attempt = 1;attempt <= maxRetries; attempt++) {
|
|
6946
|
-
const startMs = Date.now();
|
|
6947
|
-
try {
|
|
6948
|
-
logger.info(`[downloader] 开始下载 (attempt ${attempt}/${maxRetries}): ${url}`);
|
|
6949
|
-
const controller = new AbortController;
|
|
6950
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
6951
|
-
try {
|
|
6952
|
-
const res = await fetch(url, { signal: controller.signal });
|
|
6953
|
-
if (!res.ok) {
|
|
6954
|
-
throw new Error(`HTTP ${res.status} ${res.statusText}`);
|
|
6955
|
-
}
|
|
6956
|
-
if (!res.body) {
|
|
6957
|
-
throw new Error("响应体为空");
|
|
6958
|
-
}
|
|
6959
|
-
const writeStream = import_node_fs11.createWriteStream(destPath);
|
|
6960
|
-
const readable = import_node_stream.Readable.fromWeb(res.body);
|
|
6961
|
-
await import_promises3.pipeline(readable, writeStream);
|
|
6962
|
-
const elapsed = Date.now() - startMs;
|
|
6963
|
-
const fileSize = import_node_fs11.existsSync(destPath) ? import_node_fs11.statSync(destPath).size : 0;
|
|
6964
|
-
logger.info(`[downloader] 下载完成: ${destPath} (${formatBytes(fileSize)}, ${elapsed}ms)`);
|
|
6965
|
-
return { ok: true, sizeBytes: fileSize, elapsedMs: elapsed };
|
|
6966
|
-
} finally {
|
|
6967
|
-
clearTimeout(timer);
|
|
6968
|
-
}
|
|
6969
|
-
} catch (err) {
|
|
6970
|
-
lastError = err?.message ?? String(err);
|
|
6971
|
-
try {
|
|
6972
|
-
if (import_node_fs11.existsSync(destPath))
|
|
6973
|
-
import_node_fs11.unlinkSync(destPath);
|
|
6974
|
-
} catch {}
|
|
6975
|
-
const isAbort = err?.name === "AbortError";
|
|
6976
|
-
logger.warn(`[downloader] 下载失败 (attempt ${attempt}/${maxRetries}): ${isAbort ? "超时" : lastError}`);
|
|
6977
|
-
if (attempt < maxRetries) {
|
|
6978
|
-
const delay = retryBackoffMs * Math.pow(2, attempt - 1);
|
|
6979
|
-
logger.info(`[downloader] ${delay}ms 后重试...`);
|
|
6980
|
-
await sleep(delay);
|
|
6981
|
-
}
|
|
6982
|
-
}
|
|
6983
|
-
}
|
|
6984
|
-
return { ok: false, error: lastError ?? "下载失败" };
|
|
6985
|
-
}
|
|
6986
|
-
async function downloadRecordingFiles(ossAudioUrl, ossSrtUrl, audioDestPath, srtDestPath, logger, options) {
|
|
6987
|
-
const audio = await downloadFile(ossAudioUrl, audioDestPath, logger, options);
|
|
6988
|
-
let srt = null;
|
|
6989
|
-
if (ossSrtUrl) {
|
|
6990
|
-
srt = await downloadFile(ossSrtUrl, srtDestPath, logger, options);
|
|
6991
|
-
if (!srt.ok) {
|
|
6992
|
-
logger.warn(`[downloader] 打点文件下载失败(非致命): ${srt.error}`);
|
|
6993
|
-
}
|
|
6994
|
-
}
|
|
6995
|
-
return { audio, srt };
|
|
6996
|
-
}
|
|
6997
|
-
function formatBytes(bytes) {
|
|
6998
|
-
if (bytes < 1024)
|
|
6999
|
-
return `${bytes}B`;
|
|
7000
|
-
if (bytes < 1024 * 1024)
|
|
7001
|
-
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
7002
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
7003
|
-
}
|
|
7004
|
-
function sleep(ms) {
|
|
7005
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
7006
|
-
}
|
|
7007
6931
|
// src/vendor/recording/asr.ts
|
|
7008
|
-
var
|
|
7009
|
-
var
|
|
6932
|
+
var import_node_fs15 = require("node:fs");
|
|
6933
|
+
var import_node_path11 = require("node:path");
|
|
7010
6934
|
|
|
7011
6935
|
// src/vendor/auth/credentials.ts
|
|
7012
|
-
var import_node_fs14 = require("node:fs");
|
|
7013
|
-
|
|
7014
|
-
// src/vendor/profile/detect.ts
|
|
7015
6936
|
var import_node_fs13 = require("node:fs");
|
|
7016
|
-
var import_node_path10 = require("node:path");
|
|
7017
6937
|
|
|
7018
|
-
// src/vendor/profile/
|
|
6938
|
+
// src/vendor/profile/detect.ts
|
|
7019
6939
|
var import_node_fs12 = require("node:fs");
|
|
7020
6940
|
var import_node_path9 = require("node:path");
|
|
6941
|
+
|
|
6942
|
+
// src/vendor/profile/paths.ts
|
|
6943
|
+
var import_node_fs11 = require("node:fs");
|
|
6944
|
+
var import_node_path8 = require("node:path");
|
|
7021
6945
|
var DEFAULT_JVSCLAW_STATE_DIR = "/home/admin/.openclaw";
|
|
7022
6946
|
var PHONE_NOTIFICATIONS_STATE_DIR_ENV = "PHONE_NOTIFICATIONS_STATE_DIR";
|
|
7023
6947
|
var PHONE_NOTIFICATIONS_CONFIG_PATH_ENV = "PHONE_NOTIFICATIONS_CONFIG_PATH";
|
|
@@ -7039,24 +6963,24 @@ function expandUserPath(value) {
|
|
|
7039
6963
|
return homeDir();
|
|
7040
6964
|
}
|
|
7041
6965
|
if (value.startsWith("~/")) {
|
|
7042
|
-
return
|
|
6966
|
+
return import_node_path8.join(homeDir(), value.slice(2));
|
|
7043
6967
|
}
|
|
7044
6968
|
return value;
|
|
7045
6969
|
}
|
|
7046
6970
|
function candidateMetaPaths() {
|
|
7047
6971
|
const home = homeDir();
|
|
7048
6972
|
return [
|
|
7049
|
-
|
|
7050
|
-
|
|
6973
|
+
import_node_path8.join(home, ".qclaw", "qclaw.json"),
|
|
6974
|
+
import_node_path8.join(home, ".qclow", "qclaw.json")
|
|
7051
6975
|
];
|
|
7052
6976
|
}
|
|
7053
6977
|
function loadQClawMeta() {
|
|
7054
6978
|
for (const metaPath of candidateMetaPaths()) {
|
|
7055
|
-
if (!
|
|
6979
|
+
if (!import_node_fs11.existsSync(metaPath)) {
|
|
7056
6980
|
continue;
|
|
7057
6981
|
}
|
|
7058
6982
|
try {
|
|
7059
|
-
const parsed = JSON.parse(
|
|
6983
|
+
const parsed = JSON.parse(import_node_fs11.readFileSync(metaPath, "utf-8"));
|
|
7060
6984
|
return {
|
|
7061
6985
|
stateDir: expandUserPath(trimToUndefined2(parsed?.stateDir)),
|
|
7062
6986
|
configPath: expandUserPath(trimToUndefined2(parsed?.configPath))
|
|
@@ -7078,12 +7002,12 @@ function resolveConfigPathFromEnv() {
|
|
|
7078
7002
|
return expandUserPath(trimToUndefined2(process.env.JVSCLAW_CONFIG_PATH) ?? trimToUndefined2(process.env.OPENCLAW_CONFIG_PATH) ?? trimToUndefined2(process.env.QCLAW_CONFIG_PATH));
|
|
7079
7003
|
}
|
|
7080
7004
|
function hasOpenClawMarkers() {
|
|
7081
|
-
const baseDir =
|
|
7005
|
+
const baseDir = import_node_path8.join(homeDir(), ".openclaw");
|
|
7082
7006
|
return [
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
].some((candidate) =>
|
|
7007
|
+
import_node_path8.join(baseDir, "openclaw.json"),
|
|
7008
|
+
import_node_path8.join(baseDir, "credentials.json"),
|
|
7009
|
+
import_node_path8.join(baseDir, "extensions")
|
|
7010
|
+
].some((candidate) => import_node_fs11.existsSync(candidate));
|
|
7087
7011
|
}
|
|
7088
7012
|
function resolveHostStateDir(stateDir) {
|
|
7089
7013
|
const explicitDir = expandUserPath(trimToUndefined2(stateDir));
|
|
@@ -7095,16 +7019,16 @@ function resolveHostStateDir(stateDir) {
|
|
|
7095
7019
|
return envDir;
|
|
7096
7020
|
}
|
|
7097
7021
|
if (hasOpenClawMarkers()) {
|
|
7098
|
-
return
|
|
7022
|
+
return import_node_path8.join(homeDir(), ".openclaw");
|
|
7099
7023
|
}
|
|
7100
7024
|
const meta = loadQClawMeta();
|
|
7101
7025
|
if (meta?.stateDir) {
|
|
7102
7026
|
return meta.stateDir;
|
|
7103
7027
|
}
|
|
7104
7028
|
if (meta?.configPath) {
|
|
7105
|
-
return
|
|
7029
|
+
return import_node_path8.dirname(meta.configPath);
|
|
7106
7030
|
}
|
|
7107
|
-
return
|
|
7031
|
+
return import_node_path8.join(homeDir(), ".openclaw");
|
|
7108
7032
|
}
|
|
7109
7033
|
function resolvePersistedProfileStateDirs() {
|
|
7110
7034
|
const dirs = [];
|
|
@@ -7130,7 +7054,7 @@ function readPersistedClawProfile() {
|
|
|
7130
7054
|
for (const stateDir of resolvePersistedProfileStateDirs()) {
|
|
7131
7055
|
let content;
|
|
7132
7056
|
try {
|
|
7133
|
-
content =
|
|
7057
|
+
content = import_node_fs12.readFileSync(import_node_path9.join(stateDir, ".env"), "utf-8");
|
|
7134
7058
|
} catch {
|
|
7135
7059
|
continue;
|
|
7136
7060
|
}
|
|
@@ -7154,7 +7078,7 @@ function readPluginLinkSecret(configPath) {
|
|
|
7154
7078
|
return;
|
|
7155
7079
|
let config;
|
|
7156
7080
|
try {
|
|
7157
|
-
config = JSON.parse(
|
|
7081
|
+
config = JSON.parse(import_node_fs12.readFileSync(configPath, "utf-8"));
|
|
7158
7082
|
} catch {
|
|
7159
7083
|
return;
|
|
7160
7084
|
}
|
|
@@ -7168,7 +7092,7 @@ function hasJvsclawLinkSecret() {
|
|
|
7168
7092
|
const paths = [
|
|
7169
7093
|
resolvePluginConfigPathOverrideFromEnv(),
|
|
7170
7094
|
resolveConfigPathFromEnv(),
|
|
7171
|
-
|
|
7095
|
+
import_node_path9.join(DEFAULT_JVSCLAW_STATE_DIR, "openclaw.json")
|
|
7172
7096
|
].filter((value, index, arr) => Boolean(value) && arr.indexOf(value) === index);
|
|
7173
7097
|
return paths.some((configPath) => Boolean(readPluginLinkSecret(configPath)));
|
|
7174
7098
|
}
|
|
@@ -7194,7 +7118,7 @@ function resolveClawKind() {
|
|
|
7194
7118
|
return "openclaw";
|
|
7195
7119
|
}
|
|
7196
7120
|
// src/vendor/profile/runtime-paths.ts
|
|
7197
|
-
var
|
|
7121
|
+
var import_node_path10 = require("node:path");
|
|
7198
7122
|
function resolveStateDir(hostStateDir) {
|
|
7199
7123
|
const override = resolvePluginStateDirOverrideFromEnv();
|
|
7200
7124
|
if (override) {
|
|
@@ -7206,7 +7130,7 @@ function resolveStateDir(hostStateDir) {
|
|
|
7206
7130
|
return resolveHostStateDir(hostStateDir);
|
|
7207
7131
|
}
|
|
7208
7132
|
function resolveStateFile(filename, hostStateDir) {
|
|
7209
|
-
return
|
|
7133
|
+
return import_node_path10.join(resolveStateDir(hostStateDir), filename);
|
|
7210
7134
|
}
|
|
7211
7135
|
// src/vendor/auth/credentials.ts
|
|
7212
7136
|
var API_KEY_ENV2 = "YOOOCLAW_API_KEY";
|
|
@@ -7215,10 +7139,10 @@ function credentialsPath() {
|
|
|
7215
7139
|
}
|
|
7216
7140
|
function readCredentials() {
|
|
7217
7141
|
const path = credentialsPath();
|
|
7218
|
-
if (!
|
|
7142
|
+
if (!import_node_fs13.existsSync(path))
|
|
7219
7143
|
return {};
|
|
7220
7144
|
try {
|
|
7221
|
-
return JSON.parse(
|
|
7145
|
+
return JSON.parse(import_node_fs13.readFileSync(path, "utf-8"));
|
|
7222
7146
|
} catch {
|
|
7223
7147
|
return {};
|
|
7224
7148
|
}
|
|
@@ -7254,7 +7178,7 @@ function requireApiKey() {
|
|
|
7254
7178
|
}
|
|
7255
7179
|
|
|
7256
7180
|
// src/vendor/env.ts
|
|
7257
|
-
var
|
|
7181
|
+
var import_node_fs14 = require("node:fs");
|
|
7258
7182
|
function parseEnvContent(content) {
|
|
7259
7183
|
const entries = new Map;
|
|
7260
7184
|
const tokens = content.split(/\r?\n/).flatMap((line) => line.split(/(?<![A-Z0-9_])(?=[A-Z_][A-Z0-9_]*=)/));
|
|
@@ -7318,9 +7242,9 @@ var VALID_ENVS = new Set([
|
|
|
7318
7242
|
]);
|
|
7319
7243
|
function readDotEnv() {
|
|
7320
7244
|
const path = resolveStateFile(".env");
|
|
7321
|
-
if (!
|
|
7245
|
+
if (!import_node_fs14.existsSync(path))
|
|
7322
7246
|
return {};
|
|
7323
|
-
return Object.fromEntries(parseEnvContent(
|
|
7247
|
+
return Object.fromEntries(parseEnvContent(import_node_fs14.readFileSync(path, "utf-8")));
|
|
7324
7248
|
}
|
|
7325
7249
|
function readPersistedEnvName() {
|
|
7326
7250
|
const fromDotEnv = readDotEnv()["PHONE_NOTIFICATIONS_ENV"]?.trim();
|
|
@@ -7423,7 +7347,7 @@ async function initializeAsr(config, dataDir, logger) {
|
|
|
7423
7347
|
}
|
|
7424
7348
|
}
|
|
7425
7349
|
async function transcribeAudio(audioFilePath, config, logger, options = {}) {
|
|
7426
|
-
if (!
|
|
7350
|
+
if (!import_node_fs15.existsSync(audioFilePath)) {
|
|
7427
7351
|
return { ok: false, error: `音频文件不存在: ${audioFilePath}` };
|
|
7428
7352
|
}
|
|
7429
7353
|
logger.info(`[asr] 开始转写: mode=${config.mode}, file=${audioFilePath}`);
|
|
@@ -7555,19 +7479,19 @@ async function runTranscriptionWorkflow(params) {
|
|
|
7555
7479
|
});
|
|
7556
7480
|
const markdown = buildTranscriptMarkdown(result, markers, recordingName, durationSec, createdAt);
|
|
7557
7481
|
const transcriptDataFilename = buildTranscriptDataFilename(recordingId);
|
|
7558
|
-
const transcriptDataPath =
|
|
7559
|
-
|
|
7482
|
+
const transcriptDataPath = import_node_path11.join(transcriptDataDir, transcriptDataFilename);
|
|
7483
|
+
import_node_fs15.writeFileSync(transcriptDataPath, JSON.stringify(transcriptData, null, 2), "utf-8");
|
|
7560
7484
|
logger.info(`[asr] 转写 JSON 已写入: ${transcriptDataPath}`);
|
|
7561
7485
|
const safeSummary = title.replace(/[/\\:*?"<>|]/g, "").trim().slice(0, 20);
|
|
7562
7486
|
const filename = safeSummary ? `${recordingId}_${safeSummary}.md` : `${recordingId}.md`;
|
|
7563
|
-
const filePath =
|
|
7564
|
-
|
|
7487
|
+
const filePath = import_node_path11.join(transcriptsDir, filename);
|
|
7488
|
+
import_node_fs15.writeFileSync(filePath, markdown, "utf-8");
|
|
7565
7489
|
logger.info(`[asr] 转写文本已写入: ${filePath}`);
|
|
7566
7490
|
let summaryFilename;
|
|
7567
7491
|
if (summary) {
|
|
7568
7492
|
summaryFilename = `${recordingId}.md`;
|
|
7569
|
-
const summaryFilePath =
|
|
7570
|
-
|
|
7493
|
+
const summaryFilePath = import_node_path11.join(summariesDir, summaryFilename);
|
|
7494
|
+
import_node_fs15.writeFileSync(summaryFilePath, summary, "utf-8");
|
|
7571
7495
|
logger.info(`[asr] 摘要文本已写入: ${summaryFilePath}`);
|
|
7572
7496
|
}
|
|
7573
7497
|
return {
|
|
@@ -7710,7 +7634,7 @@ async function pollLongRecordingTaskResult(params) {
|
|
|
7710
7634
|
const msg = err?.message ?? String(err);
|
|
7711
7635
|
logger.warn(`[asr-query] 长录音任务查询网络异常: taskId=${taskId}, attempt=${attempt}, error=${msg} — 等待下次轮询`);
|
|
7712
7636
|
if (attempt < DEFAULT_LONG_RECORDING_MAX_POLL_ATTEMPTS) {
|
|
7713
|
-
await
|
|
7637
|
+
await sleep(pollIntervalMs);
|
|
7714
7638
|
continue;
|
|
7715
7639
|
}
|
|
7716
7640
|
return {
|
|
@@ -7723,7 +7647,7 @@ async function pollLongRecordingTaskResult(params) {
|
|
|
7723
7647
|
if (isRetryableHttpStatus(res.status)) {
|
|
7724
7648
|
logger.warn(`[asr-query] 长录音任务查询暂时失败: taskId=${taskId}, attempt=${attempt}, status=${res.status}, body=${errText.slice(0, 200)} — 等待下次轮询`);
|
|
7725
7649
|
if (attempt < DEFAULT_LONG_RECORDING_MAX_POLL_ATTEMPTS) {
|
|
7726
|
-
await
|
|
7650
|
+
await sleep(pollIntervalMs);
|
|
7727
7651
|
continue;
|
|
7728
7652
|
}
|
|
7729
7653
|
} else {
|
|
@@ -7767,7 +7691,7 @@ async function pollLongRecordingTaskResult(params) {
|
|
|
7767
7691
|
};
|
|
7768
7692
|
}
|
|
7769
7693
|
if (attempt < DEFAULT_LONG_RECORDING_MAX_POLL_ATTEMPTS) {
|
|
7770
|
-
await
|
|
7694
|
+
await sleep(pollIntervalMs);
|
|
7771
7695
|
}
|
|
7772
7696
|
}
|
|
7773
7697
|
return {
|
|
@@ -7916,7 +7840,7 @@ function stringifyForLog(value, maxLength = 500) {
|
|
|
7916
7840
|
return String(value).slice(0, maxLength);
|
|
7917
7841
|
}
|
|
7918
7842
|
}
|
|
7919
|
-
async function
|
|
7843
|
+
async function sleep(ms) {
|
|
7920
7844
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
7921
7845
|
}
|
|
7922
7846
|
function isRetryableHttpStatus(status) {
|
|
@@ -7953,7 +7877,7 @@ async function fetchWithRetry(url, init, options) {
|
|
|
7953
7877
|
const errText = await res.text().catch(() => "");
|
|
7954
7878
|
const delay = baseBackoff * Math.pow(2, attempt - 1);
|
|
7955
7879
|
options.logger.warn(`[${options.context}] HTTP ${res.status} (attempt ${attempt}/${maxAttempts}), ${delay}ms 后重试, body=${errText.slice(0, 200)}`);
|
|
7956
|
-
await
|
|
7880
|
+
await sleep(delay);
|
|
7957
7881
|
continue;
|
|
7958
7882
|
}
|
|
7959
7883
|
return res;
|
|
@@ -7963,7 +7887,7 @@ async function fetchWithRetry(url, init, options) {
|
|
|
7963
7887
|
const delay = baseBackoff * Math.pow(2, attempt - 1);
|
|
7964
7888
|
const msg = err?.message ?? String(err);
|
|
7965
7889
|
options.logger.warn(`[${options.context}] 网络异常 (attempt ${attempt}/${maxAttempts}): ${msg}, ${delay}ms 后重试`);
|
|
7966
|
-
await
|
|
7890
|
+
await sleep(delay);
|
|
7967
7891
|
continue;
|
|
7968
7892
|
}
|
|
7969
7893
|
}
|
|
@@ -7998,14 +7922,83 @@ function formatTranscriptSegmentText(segment) {
|
|
|
7998
7922
|
}
|
|
7999
7923
|
return text;
|
|
8000
7924
|
}
|
|
8001
|
-
// src/vendor/recording/
|
|
8002
|
-
var
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
7925
|
+
// src/vendor/recording/downloader.ts
|
|
7926
|
+
var import_node_fs16 = require("node:fs");
|
|
7927
|
+
var import_node_path12 = require("node:path");
|
|
7928
|
+
var import_promises3 = require("node:stream/promises");
|
|
7929
|
+
var import_node_stream = require("node:stream");
|
|
7930
|
+
var DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
7931
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
7932
|
+
var DEFAULT_RETRY_BACKOFF_MS = 2000;
|
|
7933
|
+
async function downloadFile(url, destPath, logger, options) {
|
|
7934
|
+
const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
7935
|
+
const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
7936
|
+
const retryBackoffMs = options?.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS;
|
|
7937
|
+
import_node_fs16.mkdirSync(import_node_path12.dirname(destPath), { recursive: true });
|
|
7938
|
+
let lastError;
|
|
7939
|
+
for (let attempt = 1;attempt <= maxRetries; attempt++) {
|
|
7940
|
+
const startMs = Date.now();
|
|
7941
|
+
try {
|
|
7942
|
+
logger.info(`[downloader] 开始下载 (attempt ${attempt}/${maxRetries}): ${url}`);
|
|
7943
|
+
const controller = new AbortController;
|
|
7944
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
7945
|
+
try {
|
|
7946
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
7947
|
+
if (!res.ok) {
|
|
7948
|
+
throw new Error(`HTTP ${res.status} ${res.statusText}`);
|
|
7949
|
+
}
|
|
7950
|
+
if (!res.body) {
|
|
7951
|
+
throw new Error("响应体为空");
|
|
7952
|
+
}
|
|
7953
|
+
const writeStream = import_node_fs16.createWriteStream(destPath);
|
|
7954
|
+
const readable = import_node_stream.Readable.fromWeb(res.body);
|
|
7955
|
+
await import_promises3.pipeline(readable, writeStream);
|
|
7956
|
+
const elapsed = Date.now() - startMs;
|
|
7957
|
+
const fileSize = import_node_fs16.existsSync(destPath) ? import_node_fs16.statSync(destPath).size : 0;
|
|
7958
|
+
logger.info(`[downloader] 下载完成: ${destPath} (${formatBytes(fileSize)}, ${elapsed}ms)`);
|
|
7959
|
+
return { ok: true, sizeBytes: fileSize, elapsedMs: elapsed };
|
|
7960
|
+
} finally {
|
|
7961
|
+
clearTimeout(timer);
|
|
7962
|
+
}
|
|
7963
|
+
} catch (err) {
|
|
7964
|
+
lastError = err?.message ?? String(err);
|
|
7965
|
+
try {
|
|
7966
|
+
if (import_node_fs16.existsSync(destPath))
|
|
7967
|
+
import_node_fs16.unlinkSync(destPath);
|
|
7968
|
+
} catch {}
|
|
7969
|
+
const isAbort = err?.name === "AbortError";
|
|
7970
|
+
logger.warn(`[downloader] 下载失败 (attempt ${attempt}/${maxRetries}): ${isAbort ? "超时" : lastError}`);
|
|
7971
|
+
if (attempt < maxRetries) {
|
|
7972
|
+
const delay = retryBackoffMs * Math.pow(2, attempt - 1);
|
|
7973
|
+
logger.info(`[downloader] ${delay}ms 后重试...`);
|
|
7974
|
+
await sleep2(delay);
|
|
7975
|
+
}
|
|
7976
|
+
}
|
|
7977
|
+
}
|
|
7978
|
+
return { ok: false, error: lastError ?? "下载失败" };
|
|
7979
|
+
}
|
|
7980
|
+
async function downloadRecordingFiles(ossAudioUrl, ossSrtUrl, audioDestPath, srtDestPath, logger, options) {
|
|
7981
|
+
const audio = await downloadFile(ossAudioUrl, audioDestPath, logger, options);
|
|
7982
|
+
let srt = null;
|
|
7983
|
+
if (ossSrtUrl) {
|
|
7984
|
+
srt = await downloadFile(ossSrtUrl, srtDestPath, logger, options);
|
|
7985
|
+
if (!srt.ok) {
|
|
7986
|
+
logger.warn(`[downloader] 打点文件下载失败(非致命): ${srt.error}`);
|
|
7987
|
+
}
|
|
7988
|
+
}
|
|
7989
|
+
return { audio, srt };
|
|
7990
|
+
}
|
|
7991
|
+
function formatBytes(bytes) {
|
|
7992
|
+
if (bytes < 1024)
|
|
7993
|
+
return `${bytes}B`;
|
|
7994
|
+
if (bytes < 1024 * 1024)
|
|
7995
|
+
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
7996
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
7997
|
+
}
|
|
7998
|
+
function sleep2(ms) {
|
|
7999
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8000
|
+
}
|
|
8001
|
+
|
|
8009
8002
|
// src/vendor/recording/handler.ts
|
|
8010
8003
|
function emitRecordingStatus(recordingId, storage2, logger, notifyStatus, error, extras) {
|
|
8011
8004
|
if (!notifyStatus) {
|
|
@@ -9553,8 +9546,8 @@ function quantizeWindow(value) {
|
|
|
9553
9546
|
// src/vendor/light/sender.ts
|
|
9554
9547
|
async function sendLightEffect(apiKey, segments, logger, repeatInput, reason, title) {
|
|
9555
9548
|
const apiUrl = getEnvUrls().lightApiUrl;
|
|
9556
|
-
const appKey = "";
|
|
9557
|
-
const templateId = "";
|
|
9549
|
+
const appKey = "7Q617S1G5WD274JI";
|
|
9550
|
+
const templateId = "1990771146010017800";
|
|
9558
9551
|
const resolvedTitle = resolveLightTitle(title, reason, segments);
|
|
9559
9552
|
logger?.info(`Light sender: apiUrl=${apiUrl ?? "UNSET"}, appKey=${appKey ? appKey.substring(0, 8) + "…" : "UNSET"}, templateId=${templateId ?? "UNSET"}, apiKey=${apiKey ? apiKey.substring(0, 20) + "…" : "EMPTY"}, title=${resolvedTitle}, reason=${reason ?? ""}, segments=${JSON.stringify(segments)}`);
|
|
9560
9553
|
if (!apiUrl || !appKey || !templateId) {
|
|
@@ -14713,5 +14706,5 @@ async function run(argv = process.argv) {
|
|
|
14713
14706
|
// src/bin.ts
|
|
14714
14707
|
run(process.argv);
|
|
14715
14708
|
|
|
14716
|
-
//# debugId=
|
|
14709
|
+
//# debugId=FB3319ED48E41BED64756E2164756E21
|
|
14717
14710
|
//# sourceMappingURL=bin.cjs.map
|