@mingxy/ocosay 1.1.23 → 1.1.25
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/core/dependency-detector.d.ts +26 -0
- package/dist/core/dependency-detector.js +52 -0
- package/dist/core/dependency-installer.d.ts +15 -0
- package/dist/core/dependency-installer.js +175 -0
- package/dist/core/dependency-mapper.d.ts +59 -0
- package/dist/core/dependency-mapper.js +246 -0
- package/dist/package.json +1 -1
- package/dist/plugin.js +489 -69
- package/package.json +1 -1
package/dist/plugin.js
CHANGED
|
@@ -2437,7 +2437,7 @@ var require_thread_stream = __commonJS({
|
|
|
2437
2437
|
var require_transport = __commonJS({
|
|
2438
2438
|
"node_modules/pino/lib/transport.js"(exports, module) {
|
|
2439
2439
|
"use strict";
|
|
2440
|
-
var { createRequire:
|
|
2440
|
+
var { createRequire: createRequire3 } = __require("module");
|
|
2441
2441
|
var { existsSync: existsSync8 } = __require("node:fs");
|
|
2442
2442
|
var getCallers = require_caller();
|
|
2443
2443
|
var { join: join9, isAbsolute, sep } = __require("node:path");
|
|
@@ -2640,7 +2640,7 @@ var require_transport = __commonJS({
|
|
|
2640
2640
|
for (const filePath of callers) {
|
|
2641
2641
|
try {
|
|
2642
2642
|
const context = filePath === "node:repl" ? process.cwd() + sep : filePath;
|
|
2643
|
-
fixTarget2 =
|
|
2643
|
+
fixTarget2 = createRequire3(context).resolve(origin);
|
|
2644
2644
|
break;
|
|
2645
2645
|
} catch (err) {
|
|
2646
2646
|
continue;
|
|
@@ -9901,13 +9901,365 @@ import { readFileSync as readFileSync2, existsSync as existsSync7, writeFileSync
|
|
|
9901
9901
|
import { fileURLToPath } from "url";
|
|
9902
9902
|
import { dirname as dirname2, join as join8 } from "path";
|
|
9903
9903
|
import { homedir as homedir3 } from "os";
|
|
9904
|
+
import { execSync as execSync4 } from "child_process";
|
|
9905
|
+
import { createRequire as createRequire2 } from "module";
|
|
9906
|
+
|
|
9907
|
+
// src/core/dependency-detector.ts
|
|
9904
9908
|
import { execSync as execSync2 } from "child_process";
|
|
9909
|
+
function parseMissingHeaders(errorOutput) {
|
|
9910
|
+
const pattern = /fatal error:\s+([^:]+):\s+No such file or directory/g;
|
|
9911
|
+
const headers = [];
|
|
9912
|
+
let match = pattern.exec(errorOutput);
|
|
9913
|
+
while (match !== null) {
|
|
9914
|
+
headers.push(match[1]);
|
|
9915
|
+
match = pattern.exec(errorOutput);
|
|
9916
|
+
}
|
|
9917
|
+
return headers;
|
|
9918
|
+
}
|
|
9919
|
+
function execCapture(cmd, cwd) {
|
|
9920
|
+
try {
|
|
9921
|
+
const stdout = execSync2(cmd, {
|
|
9922
|
+
cwd,
|
|
9923
|
+
encoding: "utf8",
|
|
9924
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
9925
|
+
});
|
|
9926
|
+
return { success: true, stdout, stderr: "" };
|
|
9927
|
+
} catch (err) {
|
|
9928
|
+
const error = err;
|
|
9929
|
+
return {
|
|
9930
|
+
success: false,
|
|
9931
|
+
stdout: error.stdout ? error.stdout.toString() : "",
|
|
9932
|
+
stderr: error.stderr ? error.stderr.toString() : ""
|
|
9933
|
+
};
|
|
9934
|
+
}
|
|
9935
|
+
}
|
|
9936
|
+
function detectMissingDependencies(cmd, cwd) {
|
|
9937
|
+
const result = execCapture(cmd, cwd);
|
|
9938
|
+
const missingHeaders = parseMissingHeaders(result.stderr);
|
|
9939
|
+
return {
|
|
9940
|
+
missingHeaders,
|
|
9941
|
+
rawOutput: result.stderr
|
|
9942
|
+
};
|
|
9943
|
+
}
|
|
9944
|
+
|
|
9945
|
+
// src/core/dependency-mapper.ts
|
|
9905
9946
|
import { createRequire } from "module";
|
|
9906
|
-
var logger8 = createModuleLogger("Plugin");
|
|
9907
9947
|
var require2 = createRequire(import.meta.url);
|
|
9908
|
-
var
|
|
9909
|
-
|
|
9910
|
-
|
|
9948
|
+
var HEADER_TO_PACKAGE = [
|
|
9949
|
+
// ALSA - Linux音频库
|
|
9950
|
+
{
|
|
9951
|
+
header: "alsa/asoundlib.h",
|
|
9952
|
+
package: "libasound2-dev"
|
|
9953
|
+
},
|
|
9954
|
+
// PortAudio - 跨平台音频I/O库
|
|
9955
|
+
{
|
|
9956
|
+
header: "portaudio.h",
|
|
9957
|
+
package: "libportaudio-dev",
|
|
9958
|
+
packageMac: "portaudio",
|
|
9959
|
+
packageWin: "portaudio"
|
|
9960
|
+
},
|
|
9961
|
+
// FFmpeg相关
|
|
9962
|
+
{
|
|
9963
|
+
header: "libavcodec/avcodec.h",
|
|
9964
|
+
package: "libavcodec-dev",
|
|
9965
|
+
packageMac: "ffmpeg",
|
|
9966
|
+
packageWin: "ffmpeg"
|
|
9967
|
+
},
|
|
9968
|
+
{
|
|
9969
|
+
header: "libavformat/avformat.h",
|
|
9970
|
+
package: "libavformat-dev",
|
|
9971
|
+
packageMac: "ffmpeg",
|
|
9972
|
+
packageWin: "ffmpeg"
|
|
9973
|
+
},
|
|
9974
|
+
{
|
|
9975
|
+
header: "libavutil/avutil.h",
|
|
9976
|
+
package: "libavutil-dev",
|
|
9977
|
+
packageMac: "ffmpeg",
|
|
9978
|
+
packageWin: "ffmpeg"
|
|
9979
|
+
},
|
|
9980
|
+
{
|
|
9981
|
+
header: "libswresample/swresample.h",
|
|
9982
|
+
package: "libswresample-dev",
|
|
9983
|
+
packageMac: "ffmpeg",
|
|
9984
|
+
packageWin: "ffmpeg"
|
|
9985
|
+
},
|
|
9986
|
+
// OpenAL - 3D音频API
|
|
9987
|
+
{
|
|
9988
|
+
header: "AL/al.h",
|
|
9989
|
+
package: "libopenal-dev",
|
|
9990
|
+
packageMac: "openal",
|
|
9991
|
+
packageWin: "openal"
|
|
9992
|
+
},
|
|
9993
|
+
// SDL - 多媒体库
|
|
9994
|
+
{
|
|
9995
|
+
header: "SDL2/SDL.h",
|
|
9996
|
+
package: "libsdl2-dev",
|
|
9997
|
+
packageMac: "sdl2",
|
|
9998
|
+
packageWin: "sdl2"
|
|
9999
|
+
},
|
|
10000
|
+
// PulseAudio - Linux音频服务
|
|
10001
|
+
{
|
|
10002
|
+
header: "pulse/pulseaudio.h",
|
|
10003
|
+
package: "libpulse-dev"
|
|
10004
|
+
},
|
|
10005
|
+
// CoreAudio - macOS音频框架 (无头文件,纯框架)
|
|
10006
|
+
{
|
|
10007
|
+
header: "CoreAudio/CoreAudio.h",
|
|
10008
|
+
package: "\u81FA",
|
|
10009
|
+
// macOS系统框架,无需安装包
|
|
10010
|
+
packageMac: ""
|
|
10011
|
+
},
|
|
10012
|
+
// Windows特定
|
|
10013
|
+
{
|
|
10014
|
+
header: "windows.h",
|
|
10015
|
+
package: "",
|
|
10016
|
+
// Linux上不存在
|
|
10017
|
+
packageWin: ""
|
|
10018
|
+
// Windows SDK自带
|
|
10019
|
+
}
|
|
10020
|
+
];
|
|
10021
|
+
function detectPlatform() {
|
|
10022
|
+
const platform = process.platform;
|
|
10023
|
+
const isWsl3 = detectWsl();
|
|
10024
|
+
let packageManager;
|
|
10025
|
+
let installCommand;
|
|
10026
|
+
if (platform === "linux" || isWsl3) {
|
|
10027
|
+
packageManager = "apt-get";
|
|
10028
|
+
installCommand = "sudo apt-get install -y";
|
|
10029
|
+
} else if (platform === "darwin") {
|
|
10030
|
+
packageManager = "brew";
|
|
10031
|
+
installCommand = "brew install";
|
|
10032
|
+
} else {
|
|
10033
|
+
packageManager = "choco";
|
|
10034
|
+
installCommand = "choco install -y";
|
|
10035
|
+
}
|
|
10036
|
+
return {
|
|
10037
|
+
platform,
|
|
10038
|
+
isWsl: isWsl3,
|
|
10039
|
+
packageManager,
|
|
10040
|
+
installCommand
|
|
10041
|
+
};
|
|
10042
|
+
}
|
|
10043
|
+
function detectWsl() {
|
|
10044
|
+
if (process.platform !== "linux") return false;
|
|
10045
|
+
try {
|
|
10046
|
+
return require2("fs").readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft");
|
|
10047
|
+
} catch {
|
|
10048
|
+
return false;
|
|
10049
|
+
}
|
|
10050
|
+
}
|
|
10051
|
+
function getPackageForPlatform(mapping, platform, isWsl3) {
|
|
10052
|
+
if (platform === "win32") {
|
|
10053
|
+
if (isWsl3) {
|
|
10054
|
+
return mapping.package || null;
|
|
10055
|
+
}
|
|
10056
|
+
return mapping.packageWin || mapping.package || null;
|
|
10057
|
+
}
|
|
10058
|
+
if (platform === "darwin") {
|
|
10059
|
+
if (mapping.packageMac === "") return null;
|
|
10060
|
+
return mapping.packageMac || mapping.package || null;
|
|
10061
|
+
}
|
|
10062
|
+
if (mapping.package === "") return null;
|
|
10063
|
+
return mapping.package || null;
|
|
10064
|
+
}
|
|
10065
|
+
function mapHeaderToPackages(header, platform) {
|
|
10066
|
+
const exactMatch = HEADER_TO_PACKAGE.find(
|
|
10067
|
+
(m) => m.header.toLowerCase() === header.toLowerCase()
|
|
10068
|
+
);
|
|
10069
|
+
if (exactMatch) {
|
|
10070
|
+
const pkg = getPackageForPlatform(exactMatch, platform, detectWsl());
|
|
10071
|
+
if (pkg && pkg.length > 0 && pkg !== "\u81FA") {
|
|
10072
|
+
return [pkg];
|
|
10073
|
+
}
|
|
10074
|
+
return [];
|
|
10075
|
+
}
|
|
10076
|
+
const headerBasename = header.split("/").pop()?.toLowerCase() || "";
|
|
10077
|
+
const fuzzyMatch = HEADER_TO_PACKAGE.find((m) => {
|
|
10078
|
+
const mappingBasename = m.header.split("/").pop()?.toLowerCase() || "";
|
|
10079
|
+
return mappingBasename === headerBasename;
|
|
10080
|
+
});
|
|
10081
|
+
if (fuzzyMatch) {
|
|
10082
|
+
const pkg = getPackageForPlatform(fuzzyMatch, platform, detectWsl());
|
|
10083
|
+
if (pkg && pkg.length > 0 && pkg !== "\u81FA") {
|
|
10084
|
+
return [pkg];
|
|
10085
|
+
}
|
|
10086
|
+
return [];
|
|
10087
|
+
}
|
|
10088
|
+
return [];
|
|
10089
|
+
}
|
|
10090
|
+
function mapHeadersToPackages(headers, platform) {
|
|
10091
|
+
const packageSet = /* @__PURE__ */ new Set();
|
|
10092
|
+
for (const header of headers) {
|
|
10093
|
+
const packages = mapHeaderToPackages(header, platform);
|
|
10094
|
+
for (const pkg of packages) {
|
|
10095
|
+
if (pkg.length > 0) {
|
|
10096
|
+
packageSet.add(pkg);
|
|
10097
|
+
}
|
|
10098
|
+
}
|
|
10099
|
+
}
|
|
10100
|
+
return Array.from(packageSet);
|
|
10101
|
+
}
|
|
10102
|
+
|
|
10103
|
+
// src/core/dependency-installer.ts
|
|
10104
|
+
import { execSync as execSync3 } from "child_process";
|
|
10105
|
+
var logger8 = createModuleLogger("DependencyInstaller");
|
|
10106
|
+
function getInstallCommandPrefix() {
|
|
10107
|
+
const { platform, isWsl: isWsl3 } = detectPlatform();
|
|
10108
|
+
if (platform === "linux" || isWsl3) {
|
|
10109
|
+
return "sudo apt-get install -y";
|
|
10110
|
+
} else if (platform === "darwin") {
|
|
10111
|
+
return "brew install";
|
|
10112
|
+
}
|
|
10113
|
+
return "choco install -y";
|
|
10114
|
+
}
|
|
10115
|
+
function getCheckCommand(packageName) {
|
|
10116
|
+
const { platform, isWsl: isWsl3 } = detectPlatform();
|
|
10117
|
+
if (platform === "linux" || isWsl3) {
|
|
10118
|
+
return `dpkg -s ${packageName} 2>/dev/null | grep -q "Status: install ok installed"`;
|
|
10119
|
+
} else if (platform === "darwin") {
|
|
10120
|
+
return `brew list ${packageName} &>/dev/null`;
|
|
10121
|
+
}
|
|
10122
|
+
return `choco list --local-only ${packageName} &>/dev/null`;
|
|
10123
|
+
}
|
|
10124
|
+
function silentLog(level2, message, extra) {
|
|
10125
|
+
switch (level2) {
|
|
10126
|
+
case "info":
|
|
10127
|
+
logger8.info(extra || {}, message);
|
|
10128
|
+
break;
|
|
10129
|
+
case "warn":
|
|
10130
|
+
logger8.warn(extra || {}, message);
|
|
10131
|
+
break;
|
|
10132
|
+
case "error":
|
|
10133
|
+
logger8.error(extra || {}, message);
|
|
10134
|
+
break;
|
|
10135
|
+
}
|
|
10136
|
+
}
|
|
10137
|
+
function canSudoWithoutPassword() {
|
|
10138
|
+
try {
|
|
10139
|
+
execSync3("sudo -n true 2>&1", { stdio: "pipe" });
|
|
10140
|
+
return true;
|
|
10141
|
+
} catch {
|
|
10142
|
+
return false;
|
|
10143
|
+
}
|
|
10144
|
+
}
|
|
10145
|
+
async function installSystemPackages(packages, notifSvc) {
|
|
10146
|
+
const result = {
|
|
10147
|
+
success: false,
|
|
10148
|
+
installedPackages: [],
|
|
10149
|
+
failedPackages: []
|
|
10150
|
+
};
|
|
10151
|
+
const validPackages = packages.filter((p) => p && p.length > 0 && p !== "\u81FA");
|
|
10152
|
+
if (validPackages.length === 0) {
|
|
10153
|
+
silentLog("info", "\u6CA1\u6709\u9700\u8981\u5B89\u88C5\u7684\u5305");
|
|
10154
|
+
return { ...result, success: true };
|
|
10155
|
+
}
|
|
10156
|
+
silentLog("info", `\u5F00\u59CB\u5B89\u88C5\u7CFB\u7EDF\u4F9D\u8D56: ${validPackages.join(", ")}`, { packages: validPackages });
|
|
10157
|
+
notifSvc?.info("\u6B63\u5728\u5B89\u88C5\u7CFB\u7EDF\u4F9D\u8D56...", "Ocosay", 3e3);
|
|
10158
|
+
const installCommand = getInstallCommandPrefix();
|
|
10159
|
+
const fullCommand = `${installCommand} ${validPackages.join(" ")}`;
|
|
10160
|
+
silentLog("info", `\u6267\u884C\u5B89\u88C5\u547D\u4EE4: ${fullCommand}`);
|
|
10161
|
+
if (!canSudoWithoutPassword()) {
|
|
10162
|
+
const msg = "\u9700\u8981 sudo \u6743\u9650\uFF0C\u8BF7\u786E\u4FDD\u5DF2\u914D\u7F6E NOPASSWD";
|
|
10163
|
+
result.error = msg;
|
|
10164
|
+
notifSvc?.error("\u9700\u8981 sudo \u6743\u9650", "\u8BF7\u5728\u7EC8\u7AEF\u6267\u884C: sudo visudo \u6DFB\u52A0 NOPASSWD \u914D\u7F6E\uFF0C\u914D\u7F6E\u597D\u540E\u8BF7\u91CD\u542F OpenCode", 1e4);
|
|
10165
|
+
silentLog("error", msg);
|
|
10166
|
+
return result;
|
|
10167
|
+
}
|
|
10168
|
+
try {
|
|
10169
|
+
const { platform, isWsl: isWsl3 } = detectPlatform();
|
|
10170
|
+
if (platform === "linux" || isWsl3) {
|
|
10171
|
+
notifSvc?.info("\u6B63\u5728\u66F4\u65B0\u5305\u5217\u8868...", "Ocosay", 3e3);
|
|
10172
|
+
silentLog("info", "\u66F4\u65B0 apt \u5305\u5217\u8868");
|
|
10173
|
+
try {
|
|
10174
|
+
execSync3("sudo apt-get update", {
|
|
10175
|
+
timeout: 12e4,
|
|
10176
|
+
encoding: "utf8"
|
|
10177
|
+
});
|
|
10178
|
+
silentLog("info", "apt-get update \u5B8C\u6210");
|
|
10179
|
+
} catch (updateErr) {
|
|
10180
|
+
silentLog("warn", "apt-get update \u5931\u8D25\uFF0C\u7EE7\u7EED\u5C1D\u8BD5\u5B89\u88C5", { error: String(updateErr) });
|
|
10181
|
+
}
|
|
10182
|
+
}
|
|
10183
|
+
notifSvc?.info(`\u6B63\u5728\u5B89\u88C5 ${validPackages.length} \u4E2A\u5305...`, "Ocosay", 5e3);
|
|
10184
|
+
const output = execSync3(fullCommand, {
|
|
10185
|
+
timeout: 3e5,
|
|
10186
|
+
encoding: "utf8"
|
|
10187
|
+
});
|
|
10188
|
+
silentLog("info", `\u5B89\u88C5\u8F93\u51FA: ${output.substring(0, 500)}`);
|
|
10189
|
+
const verifiedPackages = [];
|
|
10190
|
+
const failedPackages = [];
|
|
10191
|
+
for (const pkg of validPackages) {
|
|
10192
|
+
const isInstalled = await verifyInstallation([pkg]);
|
|
10193
|
+
if (isInstalled) {
|
|
10194
|
+
verifiedPackages.push(pkg);
|
|
10195
|
+
silentLog("info", `\u5305 ${pkg} \u5B89\u88C5\u9A8C\u8BC1\u6210\u529F`);
|
|
10196
|
+
} else {
|
|
10197
|
+
failedPackages.push(pkg);
|
|
10198
|
+
silentLog("warn", `\u5305 ${pkg} \u5B89\u88C5\u9A8C\u8BC1\u5931\u8D25`);
|
|
10199
|
+
}
|
|
10200
|
+
}
|
|
10201
|
+
result.installedPackages = verifiedPackages;
|
|
10202
|
+
result.failedPackages = failedPackages;
|
|
10203
|
+
result.success = failedPackages.length === 0;
|
|
10204
|
+
if (result.success) {
|
|
10205
|
+
notifSvc?.success("\u7CFB\u7EDF\u4F9D\u8D56\u5B89\u88C5\u6210\u529F", verifiedPackages.join(", "), 5e3);
|
|
10206
|
+
silentLog("info", `\u6240\u6709\u5305\u5B89\u88C5\u6210\u529F: ${verifiedPackages.join(", ")}`);
|
|
10207
|
+
} else {
|
|
10208
|
+
const errorMsg = failedPackages.length > 0 ? `\u4EE5\u4E0B\u5305\u5B89\u88C5\u5931\u8D25: ${failedPackages.join(", ")}` : "\u90E8\u5206\u5305\u5B89\u88C5\u5931\u8D25";
|
|
10209
|
+
result.error = errorMsg;
|
|
10210
|
+
notifSvc?.warning("\u90E8\u5206\u4F9D\u8D56\u5B89\u88C5\u5931\u8D25", errorMsg, 8e3);
|
|
10211
|
+
silentLog("warn", errorMsg);
|
|
10212
|
+
}
|
|
10213
|
+
} catch (err) {
|
|
10214
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
10215
|
+
silentLog("error", `\u5B89\u88C5\u547D\u4EE4\u6267\u884C\u5931\u8D25: ${errorMessage}`, { error: errorMessage });
|
|
10216
|
+
if (errorMessage.includes("sudo") || errorMessage.toLowerCase().includes("password")) {
|
|
10217
|
+
result.error = "\u9700\u8981 sudo \u6743\u9650\uFF0C\u8BF7\u786E\u4FDD\u5DF2\u914D\u7F6E NOPASSWD";
|
|
10218
|
+
notifSvc?.error("\u9700\u8981 sudo \u6743\u9650", "\u8BF7\u5728\u7EC8\u7AEF\u6267\u884C: sudo visudo", 1e4);
|
|
10219
|
+
} else if (errorMessage.includes("already") || errorMessage.includes("is already")) {
|
|
10220
|
+
result.success = true;
|
|
10221
|
+
result.installedPackages = validPackages;
|
|
10222
|
+
notifSvc?.success("\u4F9D\u8D56\u5DF2\u5B58\u5728", "\u65E0\u9700\u91CD\u65B0\u5B89\u88C5", 3e3);
|
|
10223
|
+
} else {
|
|
10224
|
+
result.error = errorMessage;
|
|
10225
|
+
notifSvc?.error("\u4F9D\u8D56\u5B89\u88C5\u5931\u8D25", errorMessage.substring(0, 200), 8e3);
|
|
10226
|
+
}
|
|
10227
|
+
}
|
|
10228
|
+
return result;
|
|
10229
|
+
}
|
|
10230
|
+
async function verifyInstallation(packages) {
|
|
10231
|
+
if (packages.length === 0) {
|
|
10232
|
+
return true;
|
|
10233
|
+
}
|
|
10234
|
+
const validPackages = packages.filter((p) => p && p.length > 0 && p !== "\u81FA");
|
|
10235
|
+
if (validPackages.length === 0) {
|
|
10236
|
+
return true;
|
|
10237
|
+
}
|
|
10238
|
+
silentLog("info", `\u9A8C\u8BC1\u5305\u5B89\u88C5\u72B6\u6001: ${validPackages.join(", ")}`);
|
|
10239
|
+
try {
|
|
10240
|
+
for (const pkg of validPackages) {
|
|
10241
|
+
const checkCmd = getCheckCommand(pkg);
|
|
10242
|
+
const { success } = execCapture(checkCmd);
|
|
10243
|
+
if (!success) {
|
|
10244
|
+
silentLog("warn", `\u5305 ${pkg} \u9A8C\u8BC1\u5931\u8D25`);
|
|
10245
|
+
return false;
|
|
10246
|
+
}
|
|
10247
|
+
}
|
|
10248
|
+
silentLog("info", `\u6240\u6709\u5305\u9A8C\u8BC1\u901A\u8FC7: ${validPackages.join(", ")}`);
|
|
10249
|
+
return true;
|
|
10250
|
+
} catch (err) {
|
|
10251
|
+
silentLog("error", `\u9A8C\u8BC1\u8FC7\u7A0B\u5F02\u5E38: ${String(err)}`);
|
|
10252
|
+
return false;
|
|
10253
|
+
}
|
|
10254
|
+
}
|
|
10255
|
+
|
|
10256
|
+
// src/plugin.ts
|
|
10257
|
+
var logger9 = createModuleLogger("Plugin");
|
|
10258
|
+
var require3 = createRequire2(import.meta.url);
|
|
10259
|
+
var opencodeBinPath = execSync4("which opencode").toString().trim();
|
|
10260
|
+
var opencodeRoot = dirname2(dirname2(opencodeBinPath));
|
|
10261
|
+
var opencodeNodeModules = join8(opencodeRoot, "node_modules");
|
|
10262
|
+
var pluginRequire = createRequire2(join8(opencodeNodeModules, "package.json"));
|
|
9911
10263
|
function getSkipFilePath() {
|
|
9912
10264
|
return join8(homedir3(), ".config", "opencode", ".naudiodon_skip");
|
|
9913
10265
|
}
|
|
@@ -9918,7 +10270,7 @@ function markNaudiodonSkipped() {
|
|
|
9918
10270
|
try {
|
|
9919
10271
|
const dir = join8(homedir3(), ".config", "opencode");
|
|
9920
10272
|
if (!existsSync7(dir)) {
|
|
9921
|
-
|
|
10273
|
+
execSync4("mkdir -p", { cwd: dir });
|
|
9922
10274
|
}
|
|
9923
10275
|
writeFileSync6(getSkipFilePath(), Date.now().toString(), "utf-8");
|
|
9924
10276
|
} catch {
|
|
@@ -9926,70 +10278,70 @@ function markNaudiodonSkipped() {
|
|
|
9926
10278
|
}
|
|
9927
10279
|
async function verifyNaudiodonLoad() {
|
|
9928
10280
|
try {
|
|
9929
|
-
|
|
9930
|
-
|
|
10281
|
+
require3("naudiodon");
|
|
10282
|
+
logger9.info("naudiodon loaded successfully");
|
|
9931
10283
|
return true;
|
|
9932
10284
|
} catch (err) {
|
|
9933
|
-
|
|
10285
|
+
logger9.warn({ err }, "naudiodon load failed after rebuild");
|
|
9934
10286
|
return false;
|
|
9935
10287
|
}
|
|
9936
10288
|
}
|
|
9937
10289
|
async function rebuildNaudiodonDependency(dep) {
|
|
9938
|
-
const naudiodonPath = dirname2(
|
|
10290
|
+
const naudiodonPath = dirname2(require3.resolve("naudiodon"));
|
|
9939
10291
|
try {
|
|
9940
10292
|
notificationService.info(`\u6B63\u5728\u7F16\u8BD1 ${dep}...`, "Ocosay \u4F9D\u8D56", 4e3);
|
|
9941
|
-
|
|
10293
|
+
execSync4(`npm rebuild ${dep}`, {
|
|
9942
10294
|
cwd: naudiodonPath,
|
|
9943
10295
|
stdio: "inherit"
|
|
9944
10296
|
});
|
|
9945
|
-
|
|
10297
|
+
logger9.info(`${dep} rebuilt successfully`);
|
|
9946
10298
|
return true;
|
|
9947
10299
|
} catch (err) {
|
|
9948
|
-
|
|
10300
|
+
logger9.warn({ err }, `${dep} rebuild failed`);
|
|
9949
10301
|
return false;
|
|
9950
10302
|
}
|
|
9951
10303
|
}
|
|
9952
10304
|
async function fixNaudiodonDependencies(maxRetries = 5) {
|
|
9953
|
-
const naudiodonPath = dirname2(
|
|
10305
|
+
const naudiodonPath = dirname2(require3.resolve("naudiodon"));
|
|
9954
10306
|
const criticalDeps = ["segfault-handler", "bindings", "node-pre-gyp"];
|
|
9955
10307
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
9956
10308
|
if (await verifyNaudiodonLoad()) {
|
|
9957
10309
|
return true;
|
|
9958
10310
|
}
|
|
9959
|
-
|
|
10311
|
+
logger9.info({ attempt }, "naudiodon not loadable, trying dependency rebuild");
|
|
9960
10312
|
notificationService.info(`\u6B63\u5728\u68C0\u67E5\u4F9D\u8D56 (${attempt + 1}/${maxRetries})...`, "Ocosay", 3e3);
|
|
9961
10313
|
let anySuccess = false;
|
|
9962
10314
|
for (const dep of criticalDeps) {
|
|
9963
10315
|
try {
|
|
9964
|
-
|
|
10316
|
+
require3.resolve(dep, { paths: [naudiodonPath] });
|
|
9965
10317
|
if (await rebuildNaudiodonDependency(dep)) {
|
|
9966
10318
|
anySuccess = true;
|
|
9967
10319
|
}
|
|
9968
10320
|
} catch {
|
|
9969
10321
|
try {
|
|
9970
10322
|
notificationService.info(`\u6B63\u5728\u5B89\u88C5 ${dep}...`, "Ocosay", 4e3);
|
|
9971
|
-
|
|
10323
|
+
execSync4(`npm install ${dep}`, {
|
|
9972
10324
|
cwd: naudiodonPath,
|
|
9973
10325
|
stdio: "inherit"
|
|
9974
10326
|
});
|
|
9975
|
-
|
|
10327
|
+
logger9.info(`${dep} installed successfully`);
|
|
9976
10328
|
anySuccess = true;
|
|
9977
10329
|
} catch (installErr) {
|
|
9978
|
-
|
|
10330
|
+
logger9.warn({ err: installErr }, `${dep} install failed`);
|
|
9979
10331
|
}
|
|
9980
10332
|
}
|
|
9981
10333
|
}
|
|
9982
10334
|
if (!anySuccess || !await verifyNaudiodonLoad()) {
|
|
9983
10335
|
try {
|
|
9984
10336
|
notificationService.info("\u6B63\u5728\u91CD\u65B0\u7F16\u8BD1 naudiodon...", "Ocosay", 4e3);
|
|
9985
|
-
|
|
10337
|
+
execSync4("npm rebuild naudiodon", {
|
|
9986
10338
|
cwd: naudiodonPath,
|
|
9987
10339
|
stdio: "inherit"
|
|
9988
10340
|
});
|
|
9989
|
-
|
|
10341
|
+
logger9.info("naudiodon rebuilt");
|
|
9990
10342
|
anySuccess = true;
|
|
9991
10343
|
} catch (err) {
|
|
9992
|
-
|
|
10344
|
+
logger9.warn({ err }, "naudiodon rebuild failed");
|
|
9993
10345
|
}
|
|
9994
10346
|
}
|
|
9995
10347
|
if (await verifyNaudiodonLoad()) {
|
|
@@ -10003,25 +10355,25 @@ async function fixNaudiodonDependencies(maxRetries = 5) {
|
|
|
10003
10355
|
}
|
|
10004
10356
|
async function ensureNaudiodonCompiled() {
|
|
10005
10357
|
if (shouldSkipNaudiodon()) {
|
|
10006
|
-
|
|
10358
|
+
logger9.info("naudiodon skipped previously");
|
|
10007
10359
|
return;
|
|
10008
10360
|
}
|
|
10009
10361
|
try {
|
|
10010
|
-
|
|
10011
|
-
|
|
10362
|
+
require3("naudiodon");
|
|
10363
|
+
logger9.info("naudiodon already compiled");
|
|
10012
10364
|
return;
|
|
10013
10365
|
} catch {
|
|
10014
|
-
|
|
10366
|
+
logger9.info("naudiodon not compiled, will attempt to compile");
|
|
10015
10367
|
notificationService.info("\u6B63\u5728\u7F16\u8BD1 naudiodon...", "Ocosay \u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10016
10368
|
}
|
|
10017
10369
|
try {
|
|
10018
|
-
const naudiodonPath = dirname2(
|
|
10019
|
-
|
|
10020
|
-
|
|
10370
|
+
const naudiodonPath = dirname2(require3.resolve("naudiodon"));
|
|
10371
|
+
logger9.info({ naudiodonPath }, "found naudiodon, rebuilding");
|
|
10372
|
+
execSync4("npm rebuild naudiodon", {
|
|
10021
10373
|
cwd: naudiodonPath,
|
|
10022
10374
|
stdio: "inherit"
|
|
10023
10375
|
});
|
|
10024
|
-
|
|
10376
|
+
logger9.info("naudiodon compiled, verifying...");
|
|
10025
10377
|
const loadSuccess = await verifyNaudiodonLoad();
|
|
10026
10378
|
if (loadSuccess) {
|
|
10027
10379
|
notificationService.success("naudiodon \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
@@ -10035,18 +10387,18 @@ async function ensureNaudiodonCompiled() {
|
|
|
10035
10387
|
}
|
|
10036
10388
|
}
|
|
10037
10389
|
} catch (err) {
|
|
10038
|
-
|
|
10390
|
+
logger9.warn({ err }, "naudiodon rebuild failed, checking for PortAudio");
|
|
10039
10391
|
notificationService.warning("naudiodon \u7F16\u8BD1\u5931\u8D25", "\u6B63\u5728\u5C1D\u8BD5\u5B89\u88C5 PortAudio...", 5e3);
|
|
10040
10392
|
const installed = await installPortAudio();
|
|
10041
10393
|
if (installed.success) {
|
|
10042
10394
|
try {
|
|
10043
|
-
const naudiodonPath = dirname2(
|
|
10395
|
+
const naudiodonPath = dirname2(require3.resolve("naudiodon"));
|
|
10044
10396
|
notificationService.info("\u6B63\u5728\u91CD\u65B0\u7F16\u8BD1 naudiodon...", "Ocosay", 5e3);
|
|
10045
|
-
|
|
10397
|
+
execSync4("npm rebuild naudiodon", {
|
|
10046
10398
|
cwd: naudiodonPath,
|
|
10047
10399
|
stdio: "inherit"
|
|
10048
10400
|
});
|
|
10049
|
-
|
|
10401
|
+
logger9.info("naudiodon compiled successfully after PortAudio install");
|
|
10050
10402
|
const loadSuccess = await verifyNaudiodonLoad();
|
|
10051
10403
|
if (loadSuccess) {
|
|
10052
10404
|
notificationService.success("naudiodon \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
@@ -10060,12 +10412,12 @@ async function ensureNaudiodonCompiled() {
|
|
|
10060
10412
|
}
|
|
10061
10413
|
}
|
|
10062
10414
|
} catch (retryErr) {
|
|
10063
|
-
|
|
10415
|
+
logger9.error({ err: retryErr }, "naudiodon compile failed even after PortAudio install");
|
|
10064
10416
|
notificationService.error("naudiodon \u7F16\u8BD1\u5931\u8D25", "\u81EA\u52A8\u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u5C1D\u8BD5\u624B\u52A8\u5B89\u88C5", 8e3);
|
|
10065
10417
|
markNaudiodonSkipped();
|
|
10066
10418
|
}
|
|
10067
10419
|
} else {
|
|
10068
|
-
|
|
10420
|
+
logger9.error("PortAudio install failed");
|
|
10069
10421
|
notificationService.error("PortAudio \u5B89\u88C5\u5931\u8D25", "\u81EA\u52A8\u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u5C1D\u8BD5\u624B\u52A8\u5B89\u88C5", 8e3);
|
|
10070
10422
|
markNaudiodonSkipped();
|
|
10071
10423
|
}
|
|
@@ -10082,46 +10434,113 @@ function isModuleInstalled(moduleName) {
|
|
|
10082
10434
|
async function verifyModuleLoad(dep) {
|
|
10083
10435
|
try {
|
|
10084
10436
|
pluginRequire(dep);
|
|
10085
|
-
|
|
10437
|
+
logger9.info(`${dep} loaded successfully`);
|
|
10086
10438
|
return true;
|
|
10087
10439
|
} catch (err) {
|
|
10088
|
-
|
|
10440
|
+
logger9.warn({ err }, `${dep} load failed`);
|
|
10089
10441
|
return false;
|
|
10090
10442
|
}
|
|
10091
10443
|
}
|
|
10444
|
+
async function tryCompileSpeaker() {
|
|
10445
|
+
const dep = "speaker";
|
|
10446
|
+
const result = { success: false, stderr: "" };
|
|
10447
|
+
if (isModuleInstalled(dep)) {
|
|
10448
|
+
if (await verifyModuleLoad(dep)) {
|
|
10449
|
+
result.success = true;
|
|
10450
|
+
return result;
|
|
10451
|
+
}
|
|
10452
|
+
}
|
|
10453
|
+
if (!isModuleInstalled(dep)) {
|
|
10454
|
+
try {
|
|
10455
|
+
execSync4("npm install speaker", {
|
|
10456
|
+
cwd: opencodeNodeModules,
|
|
10457
|
+
stdio: "pipe"
|
|
10458
|
+
});
|
|
10459
|
+
} catch {
|
|
10460
|
+
}
|
|
10461
|
+
}
|
|
10462
|
+
try {
|
|
10463
|
+
execSync4("npm rebuild speaker", {
|
|
10464
|
+
cwd: opencodeNodeModules,
|
|
10465
|
+
stdio: "pipe"
|
|
10466
|
+
});
|
|
10467
|
+
if (await verifyModuleLoad(dep)) {
|
|
10468
|
+
result.success = true;
|
|
10469
|
+
}
|
|
10470
|
+
} catch (err) {
|
|
10471
|
+
result.stderr = err.stderr?.toString() || err.message || "";
|
|
10472
|
+
}
|
|
10473
|
+
return result;
|
|
10474
|
+
}
|
|
10475
|
+
async function ensureSpeakerCompiledAsync() {
|
|
10476
|
+
const compileResult = await tryCompileSpeaker();
|
|
10477
|
+
if (compileResult.success) {
|
|
10478
|
+
logger9.info("speaker compiled successfully");
|
|
10479
|
+
return;
|
|
10480
|
+
}
|
|
10481
|
+
const detectResult = detectMissingDependencies(compileResult.stderr);
|
|
10482
|
+
if (detectResult.missingHeaders.length === 0) {
|
|
10483
|
+
logger9.info("speaker compile failed with unknown error");
|
|
10484
|
+
return;
|
|
10485
|
+
}
|
|
10486
|
+
logger9.info({ missingHeaders: detectResult.missingHeaders }, "detected missing headers");
|
|
10487
|
+
const platformInfo = detectPlatform();
|
|
10488
|
+
const packages = mapHeadersToPackages(detectResult.missingHeaders, platformInfo.platform);
|
|
10489
|
+
if (packages.length === 0) {
|
|
10490
|
+
logger9.info("no known packages for missing headers");
|
|
10491
|
+
return;
|
|
10492
|
+
}
|
|
10493
|
+
logger9.info({ packages }, "mapped headers to packages, installing");
|
|
10494
|
+
await installSystemPackages(packages, notificationService);
|
|
10495
|
+
const retryResult = await tryCompileSpeaker();
|
|
10496
|
+
if (retryResult.success) {
|
|
10497
|
+
logger9.info("speaker compiled successfully after installing dependencies");
|
|
10498
|
+
} else {
|
|
10499
|
+
logger9.warn("speaker compile still failed after dependency installation");
|
|
10500
|
+
}
|
|
10501
|
+
}
|
|
10502
|
+
async function ensureSpeakerInstalledAsync() {
|
|
10503
|
+
await ensurePlaySoundInstalled();
|
|
10504
|
+
}
|
|
10505
|
+
async function initAsync() {
|
|
10506
|
+
setTimeout(async () => {
|
|
10507
|
+
await ensureSpeakerCompiledAsync();
|
|
10508
|
+
await ensureSpeakerInstalledAsync();
|
|
10509
|
+
}, 100);
|
|
10510
|
+
}
|
|
10092
10511
|
async function ensureSpeakerCompiled(maxRetries = 5) {
|
|
10093
10512
|
const dep = "speaker";
|
|
10094
10513
|
if (isModuleInstalled(dep)) {
|
|
10095
|
-
|
|
10514
|
+
logger9.info("speaker already installed");
|
|
10096
10515
|
if (await verifyModuleLoad(dep)) {
|
|
10097
10516
|
return;
|
|
10098
10517
|
}
|
|
10099
|
-
|
|
10518
|
+
logger9.info("speaker installed but not loadable, rebuilding");
|
|
10100
10519
|
notificationService.info("\u6B63\u5728\u7F16\u8BD1 speaker...", "Ocosay \u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10101
10520
|
try {
|
|
10102
|
-
|
|
10521
|
+
execSync4("npm rebuild speaker", {
|
|
10103
10522
|
cwd: opencodeNodeModules,
|
|
10104
10523
|
stdio: "inherit"
|
|
10105
10524
|
});
|
|
10106
|
-
|
|
10525
|
+
logger9.info("speaker rebuilt");
|
|
10107
10526
|
} catch (err) {
|
|
10108
|
-
|
|
10527
|
+
logger9.warn({ err }, "speaker rebuild failed");
|
|
10109
10528
|
}
|
|
10110
10529
|
if (await verifyModuleLoad(dep)) {
|
|
10111
10530
|
notificationService.success("speaker \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
10112
10531
|
return;
|
|
10113
10532
|
}
|
|
10114
10533
|
} else {
|
|
10115
|
-
|
|
10534
|
+
logger9.info("speaker not found, installing");
|
|
10116
10535
|
notificationService.info("\u6B63\u5728\u5B89\u88C5 speaker...", "Ocosay \u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10117
10536
|
try {
|
|
10118
|
-
|
|
10537
|
+
execSync4("npm install speaker", {
|
|
10119
10538
|
cwd: opencodeNodeModules,
|
|
10120
10539
|
stdio: "inherit"
|
|
10121
10540
|
});
|
|
10122
|
-
|
|
10541
|
+
logger9.info("speaker installed");
|
|
10123
10542
|
} catch (err) {
|
|
10124
|
-
|
|
10543
|
+
logger9.warn({ err }, "speaker install failed");
|
|
10125
10544
|
}
|
|
10126
10545
|
}
|
|
10127
10546
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
@@ -10129,16 +10548,16 @@ async function ensureSpeakerCompiled(maxRetries = 5) {
|
|
|
10129
10548
|
notificationService.success("speaker \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
10130
10549
|
return;
|
|
10131
10550
|
}
|
|
10132
|
-
|
|
10551
|
+
logger9.info({ attempt, dep }, "speaker not loadable, trying rebuild");
|
|
10133
10552
|
notificationService.info(`\u6B63\u5728\u91CD\u65B0\u7F16\u8BD1 speaker (${attempt + 1}/${maxRetries})...`, "Ocosay", 3e3);
|
|
10134
10553
|
try {
|
|
10135
|
-
|
|
10554
|
+
execSync4("npm rebuild speaker", {
|
|
10136
10555
|
cwd: opencodeNodeModules,
|
|
10137
10556
|
stdio: "inherit"
|
|
10138
10557
|
});
|
|
10139
|
-
|
|
10558
|
+
logger9.info("speaker rebuilt");
|
|
10140
10559
|
} catch (err) {
|
|
10141
|
-
|
|
10560
|
+
logger9.warn({ err }, "speaker rebuild failed");
|
|
10142
10561
|
}
|
|
10143
10562
|
if (await verifyModuleLoad(dep)) {
|
|
10144
10563
|
notificationService.success("speaker \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
@@ -10148,27 +10567,27 @@ async function ensureSpeakerCompiled(maxRetries = 5) {
|
|
|
10148
10567
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
10149
10568
|
}
|
|
10150
10569
|
}
|
|
10151
|
-
|
|
10570
|
+
logger9.error({ dep }, "speaker could not be compiled");
|
|
10152
10571
|
notificationService.error("speaker \u7F16\u8BD1\u5931\u8D25", "\u8BF7\u624B\u52A8\u8FD0\u884C: npm install speaker && npm rebuild speaker", 8e3);
|
|
10153
10572
|
}
|
|
10154
10573
|
async function ensurePlaySoundInstalled() {
|
|
10155
10574
|
const dep = "play-sound";
|
|
10156
10575
|
if (isModuleInstalled(dep)) {
|
|
10157
|
-
|
|
10576
|
+
logger9.info("play-sound already installed");
|
|
10158
10577
|
if (await verifyModuleLoad(dep)) {
|
|
10159
10578
|
return;
|
|
10160
10579
|
}
|
|
10161
10580
|
}
|
|
10162
|
-
|
|
10581
|
+
logger9.info("play-sound not found, installing");
|
|
10163
10582
|
notificationService.info("\u6B63\u5728\u5B89\u88C5 play-sound...", "Ocosay \u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10164
10583
|
try {
|
|
10165
|
-
|
|
10584
|
+
execSync4("npm install play-sound", {
|
|
10166
10585
|
cwd: opencodeNodeModules,
|
|
10167
10586
|
stdio: "inherit"
|
|
10168
10587
|
});
|
|
10169
|
-
|
|
10588
|
+
logger9.info("play-sound installed");
|
|
10170
10589
|
} catch (err) {
|
|
10171
|
-
|
|
10590
|
+
logger9.warn({ err }, "play-sound install failed");
|
|
10172
10591
|
notificationService.warning(
|
|
10173
10592
|
"play-sound \u5B89\u88C5\u5931\u8D25",
|
|
10174
10593
|
"\u8BF7\u624B\u52A8\u8FD0\u884C: npm install play-sound",
|
|
@@ -10192,7 +10611,7 @@ async function ensureOptionalDepsInstalled() {
|
|
|
10192
10611
|
}
|
|
10193
10612
|
function execCmd2(cmd) {
|
|
10194
10613
|
try {
|
|
10195
|
-
const output =
|
|
10614
|
+
const output = execSync4(cmd, { stdio: "pipe", encoding: "utf8" });
|
|
10196
10615
|
return { success: true, output };
|
|
10197
10616
|
} catch (err) {
|
|
10198
10617
|
return { success: false, output: err.message || "" };
|
|
@@ -10201,7 +10620,7 @@ function execCmd2(cmd) {
|
|
|
10201
10620
|
function isWsl2() {
|
|
10202
10621
|
if (process.platform !== "linux") return false;
|
|
10203
10622
|
try {
|
|
10204
|
-
return
|
|
10623
|
+
return require3("fs").readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft");
|
|
10205
10624
|
} catch {
|
|
10206
10625
|
return false;
|
|
10207
10626
|
}
|
|
@@ -10238,12 +10657,12 @@ async function checkAudioEnvironmentForBackend() {
|
|
|
10238
10657
|
async function installPortAudio() {
|
|
10239
10658
|
const platform = process.platform;
|
|
10240
10659
|
const wsl = isWsl2();
|
|
10241
|
-
|
|
10660
|
+
logger9.info({ platform, wsl }, "installing PortAudio");
|
|
10242
10661
|
const runInstall = async (cmd, desc) => {
|
|
10243
|
-
|
|
10662
|
+
logger9.info(`Running: ${cmd}`);
|
|
10244
10663
|
notificationService.info(desc, "\u6B63\u5728\u5B89\u88C5...", 5e3);
|
|
10245
10664
|
try {
|
|
10246
|
-
|
|
10665
|
+
execSync4(cmd, { stdio: "inherit" });
|
|
10247
10666
|
return true;
|
|
10248
10667
|
} catch (err) {
|
|
10249
10668
|
const msg = err.message || "";
|
|
@@ -10253,15 +10672,15 @@ async function installPortAudio() {
|
|
|
10253
10672
|
"# \u8BF7\u5728WSL\u7EC8\u7AEF\u6267\u884C\u4E00\u6B21\nsudo visudo\n# \u6DFB\u52A0\u884C\uFF1Ayour user name ALL=(ALL) NOPASSWD: ALL",
|
|
10254
10673
|
1e4
|
|
10255
10674
|
);
|
|
10256
|
-
|
|
10675
|
+
logger9.error({ err }, "\u9700\u8981 sudo \u6743\u9650 \u8BF7\u5728WSL\u7EC8\u7AEF\u6267\u884C\u4E00\u6B21sudo visudo # \u6DFB\u52A0\u884C\uFF1Ayour user name ALL=(ALL) NOPASSWD: ALL");
|
|
10257
10676
|
return false;
|
|
10258
10677
|
}
|
|
10259
10678
|
if (msg.includes("already") || msg.includes("is already")) {
|
|
10260
|
-
|
|
10679
|
+
logger9.info("already installed");
|
|
10261
10680
|
return true;
|
|
10262
10681
|
}
|
|
10263
10682
|
notificationService.error(desc + " \u5931\u8D25", msg.substring(0, 100), 8e3);
|
|
10264
|
-
|
|
10683
|
+
logger9.error({ err }, `install failed: ${desc}`);
|
|
10265
10684
|
return false;
|
|
10266
10685
|
}
|
|
10267
10686
|
};
|
|
@@ -10269,7 +10688,7 @@ async function installPortAudio() {
|
|
|
10269
10688
|
notificationService.info("\u68C0\u6D4B ffmpeg...", "\u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10270
10689
|
const ffmpegCheck = execCmd2("which ffplay");
|
|
10271
10690
|
if (ffmpegCheck.success) {
|
|
10272
|
-
|
|
10691
|
+
logger9.info("ffmpeg already available");
|
|
10273
10692
|
notificationService.success("ffmpeg \u5C31\u7EEA", "ffplay \u53EF\u7528\u4E8E\u65E0\u58F0\u5361\u64AD\u653E", 5e3);
|
|
10274
10693
|
} else {
|
|
10275
10694
|
notificationService.info("\u5B89\u88C5 ffmpeg...", "\u97F3\u9891\u540E\u7AEF", 5e3);
|
|
@@ -10285,7 +10704,7 @@ async function installPortAudio() {
|
|
|
10285
10704
|
}
|
|
10286
10705
|
notificationService.info("\u68C0\u6D4B\u97F3\u9891\u8BBE\u5907...", "\u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10287
10706
|
if (checkAlsa()) {
|
|
10288
|
-
|
|
10707
|
+
logger9.info("alsa-utils already available and working");
|
|
10289
10708
|
notificationService.success("alsa-utils \u5C31\u7EEA", "\u97F3\u9891\u540E\u7AEF\u5DF2\u53EF\u7528", 5e3);
|
|
10290
10709
|
return { success: true, message: "alsa" };
|
|
10291
10710
|
}
|
|
@@ -10476,8 +10895,9 @@ var server = (async (input, _options) => {
|
|
|
10476
10895
|
});
|
|
10477
10896
|
} catch (err) {
|
|
10478
10897
|
initError = err instanceof Error ? err : new Error(String(err));
|
|
10479
|
-
|
|
10898
|
+
logger9.error({ error: initError }, "initialization failed");
|
|
10480
10899
|
}
|
|
10900
|
+
initAsync();
|
|
10481
10901
|
await ensureNaudiodonCompiled();
|
|
10482
10902
|
await ensureOptionalDepsInstalled();
|
|
10483
10903
|
await checkAudioEnvironmentForBackend();
|