@mingxy/ocosay 1.1.24 → 1.1.26
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 -96
- 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,25 +9901,383 @@ 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 { exec, 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
|
|
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
|
+
function execAsync(cmd, cwd) {
|
|
10258
|
+
return new Promise((resolve) => {
|
|
10259
|
+
exec(cmd, { cwd, encoding: "utf8" }, (error, stdout, stderr) => {
|
|
10260
|
+
resolve({ stdout: stdout || "", stderr: stderr || "", error: error || void 0 });
|
|
10261
|
+
});
|
|
10262
|
+
});
|
|
10263
|
+
}
|
|
10264
|
+
var logger9 = createModuleLogger("Plugin");
|
|
10265
|
+
var require3 = createRequire2(import.meta.url);
|
|
10266
|
+
var opencodeBinPath = execSync4("which opencode").toString().trim();
|
|
9909
10267
|
var opencodeRoot = dirname2(dirname2(opencodeBinPath));
|
|
9910
10268
|
var opencodeNodeModules = join8(opencodeRoot, "node_modules");
|
|
9911
|
-
var pluginRequire =
|
|
10269
|
+
var pluginRequire = createRequire2(join8(opencodeNodeModules, "package.json"));
|
|
9912
10270
|
function getSkipFilePath() {
|
|
9913
10271
|
return join8(homedir3(), ".config", "opencode", ".naudiodon_skip");
|
|
9914
10272
|
}
|
|
9915
10273
|
function shouldSkipNaudiodon() {
|
|
9916
10274
|
return existsSync7(getSkipFilePath());
|
|
9917
10275
|
}
|
|
9918
|
-
function markNaudiodonSkipped() {
|
|
10276
|
+
async function markNaudiodonSkipped() {
|
|
9919
10277
|
try {
|
|
9920
10278
|
const dir = join8(homedir3(), ".config", "opencode");
|
|
9921
10279
|
if (!existsSync7(dir)) {
|
|
9922
|
-
|
|
10280
|
+
await execAsync("mkdir -p", dir);
|
|
9923
10281
|
}
|
|
9924
10282
|
writeFileSync6(getSkipFilePath(), Date.now().toString(), "utf-8");
|
|
9925
10283
|
} catch {
|
|
@@ -9927,70 +10285,61 @@ function markNaudiodonSkipped() {
|
|
|
9927
10285
|
}
|
|
9928
10286
|
async function verifyNaudiodonLoad() {
|
|
9929
10287
|
try {
|
|
9930
|
-
|
|
9931
|
-
|
|
10288
|
+
require3("naudiodon");
|
|
10289
|
+
logger9.info("naudiodon loaded successfully");
|
|
9932
10290
|
return true;
|
|
9933
10291
|
} catch (err) {
|
|
9934
|
-
|
|
10292
|
+
logger9.warn({ err }, "naudiodon load failed after rebuild");
|
|
9935
10293
|
return false;
|
|
9936
10294
|
}
|
|
9937
10295
|
}
|
|
9938
10296
|
async function rebuildNaudiodonDependency(dep) {
|
|
9939
|
-
const naudiodonPath = dirname2(
|
|
10297
|
+
const naudiodonPath = dirname2(require3.resolve("naudiodon"));
|
|
9940
10298
|
try {
|
|
9941
10299
|
notificationService.info(`\u6B63\u5728\u7F16\u8BD1 ${dep}...`, "Ocosay \u4F9D\u8D56", 4e3);
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
stdio: "inherit"
|
|
9945
|
-
});
|
|
9946
|
-
logger8.info(`${dep} rebuilt successfully`);
|
|
10300
|
+
await execAsync(`npm rebuild ${dep}`, naudiodonPath);
|
|
10301
|
+
logger9.info(`${dep} rebuilt successfully`);
|
|
9947
10302
|
return true;
|
|
9948
10303
|
} catch (err) {
|
|
9949
|
-
|
|
10304
|
+
logger9.warn({ err }, `${dep} rebuild failed`);
|
|
9950
10305
|
return false;
|
|
9951
10306
|
}
|
|
9952
10307
|
}
|
|
9953
10308
|
async function fixNaudiodonDependencies(maxRetries = 5) {
|
|
9954
|
-
const naudiodonPath = dirname2(
|
|
10309
|
+
const naudiodonPath = dirname2(require3.resolve("naudiodon"));
|
|
9955
10310
|
const criticalDeps = ["segfault-handler", "bindings", "node-pre-gyp"];
|
|
9956
10311
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
9957
10312
|
if (await verifyNaudiodonLoad()) {
|
|
9958
10313
|
return true;
|
|
9959
10314
|
}
|
|
9960
|
-
|
|
10315
|
+
logger9.info({ attempt }, "naudiodon not loadable, trying dependency rebuild");
|
|
9961
10316
|
notificationService.info(`\u6B63\u5728\u68C0\u67E5\u4F9D\u8D56 (${attempt + 1}/${maxRetries})...`, "Ocosay", 3e3);
|
|
9962
10317
|
let anySuccess = false;
|
|
9963
10318
|
for (const dep of criticalDeps) {
|
|
9964
10319
|
try {
|
|
9965
|
-
|
|
10320
|
+
require3.resolve(dep, { paths: [naudiodonPath] });
|
|
9966
10321
|
if (await rebuildNaudiodonDependency(dep)) {
|
|
9967
10322
|
anySuccess = true;
|
|
9968
10323
|
}
|
|
9969
10324
|
} catch {
|
|
9970
10325
|
try {
|
|
9971
10326
|
notificationService.info(`\u6B63\u5728\u5B89\u88C5 ${dep}...`, "Ocosay", 4e3);
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
stdio: "inherit"
|
|
9975
|
-
});
|
|
9976
|
-
logger8.info(`${dep} installed successfully`);
|
|
10327
|
+
await execAsync(`npm install ${dep}`, naudiodonPath);
|
|
10328
|
+
logger9.info(`${dep} installed successfully`);
|
|
9977
10329
|
anySuccess = true;
|
|
9978
10330
|
} catch (installErr) {
|
|
9979
|
-
|
|
10331
|
+
logger9.warn({ err: installErr }, `${dep} install failed`);
|
|
9980
10332
|
}
|
|
9981
10333
|
}
|
|
9982
10334
|
}
|
|
9983
10335
|
if (!anySuccess || !await verifyNaudiodonLoad()) {
|
|
9984
10336
|
try {
|
|
9985
10337
|
notificationService.info("\u6B63\u5728\u91CD\u65B0\u7F16\u8BD1 naudiodon...", "Ocosay", 4e3);
|
|
9986
|
-
|
|
9987
|
-
|
|
9988
|
-
stdio: "inherit"
|
|
9989
|
-
});
|
|
9990
|
-
logger8.info("naudiodon rebuilt");
|
|
10338
|
+
await execAsync("npm rebuild naudiodon", naudiodonPath);
|
|
10339
|
+
logger9.info("naudiodon rebuilt");
|
|
9991
10340
|
anySuccess = true;
|
|
9992
10341
|
} catch (err) {
|
|
9993
|
-
|
|
10342
|
+
logger9.warn({ err }, "naudiodon rebuild failed");
|
|
9994
10343
|
}
|
|
9995
10344
|
}
|
|
9996
10345
|
if (await verifyNaudiodonLoad()) {
|
|
@@ -10004,25 +10353,22 @@ async function fixNaudiodonDependencies(maxRetries = 5) {
|
|
|
10004
10353
|
}
|
|
10005
10354
|
async function ensureNaudiodonCompiled() {
|
|
10006
10355
|
if (shouldSkipNaudiodon()) {
|
|
10007
|
-
|
|
10356
|
+
logger9.info("naudiodon skipped previously");
|
|
10008
10357
|
return;
|
|
10009
10358
|
}
|
|
10010
10359
|
try {
|
|
10011
|
-
|
|
10012
|
-
|
|
10360
|
+
require3("naudiodon");
|
|
10361
|
+
logger9.info("naudiodon already compiled");
|
|
10013
10362
|
return;
|
|
10014
10363
|
} catch {
|
|
10015
|
-
|
|
10364
|
+
logger9.info("naudiodon not compiled, will attempt to compile");
|
|
10016
10365
|
notificationService.info("\u6B63\u5728\u7F16\u8BD1 naudiodon...", "Ocosay \u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10017
10366
|
}
|
|
10018
10367
|
try {
|
|
10019
|
-
const naudiodonPath = dirname2(
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
stdio: "inherit"
|
|
10024
|
-
});
|
|
10025
|
-
logger8.info("naudiodon compiled, verifying...");
|
|
10368
|
+
const naudiodonPath = dirname2(require3.resolve("naudiodon"));
|
|
10369
|
+
logger9.info({ naudiodonPath }, "found naudiodon, rebuilding");
|
|
10370
|
+
await execAsync("npm rebuild naudiodon", naudiodonPath);
|
|
10371
|
+
logger9.info("naudiodon compiled, verifying...");
|
|
10026
10372
|
const loadSuccess = await verifyNaudiodonLoad();
|
|
10027
10373
|
if (loadSuccess) {
|
|
10028
10374
|
notificationService.success("naudiodon \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
@@ -10036,18 +10382,15 @@ async function ensureNaudiodonCompiled() {
|
|
|
10036
10382
|
}
|
|
10037
10383
|
}
|
|
10038
10384
|
} catch (err) {
|
|
10039
|
-
|
|
10385
|
+
logger9.warn({ err }, "naudiodon rebuild failed, checking for PortAudio");
|
|
10040
10386
|
notificationService.warning("naudiodon \u7F16\u8BD1\u5931\u8D25", "\u6B63\u5728\u5C1D\u8BD5\u5B89\u88C5 PortAudio...", 5e3);
|
|
10041
10387
|
const installed = await installPortAudio();
|
|
10042
10388
|
if (installed.success) {
|
|
10043
10389
|
try {
|
|
10044
|
-
const naudiodonPath = dirname2(
|
|
10390
|
+
const naudiodonPath = dirname2(require3.resolve("naudiodon"));
|
|
10045
10391
|
notificationService.info("\u6B63\u5728\u91CD\u65B0\u7F16\u8BD1 naudiodon...", "Ocosay", 5e3);
|
|
10046
|
-
|
|
10047
|
-
|
|
10048
|
-
stdio: "inherit"
|
|
10049
|
-
});
|
|
10050
|
-
logger8.info("naudiodon compiled successfully after PortAudio install");
|
|
10392
|
+
await execAsync("npm rebuild naudiodon", naudiodonPath);
|
|
10393
|
+
logger9.info("naudiodon compiled successfully after PortAudio install");
|
|
10051
10394
|
const loadSuccess = await verifyNaudiodonLoad();
|
|
10052
10395
|
if (loadSuccess) {
|
|
10053
10396
|
notificationService.success("naudiodon \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
@@ -10061,12 +10404,12 @@ async function ensureNaudiodonCompiled() {
|
|
|
10061
10404
|
}
|
|
10062
10405
|
}
|
|
10063
10406
|
} catch (retryErr) {
|
|
10064
|
-
|
|
10407
|
+
logger9.error({ err: retryErr }, "naudiodon compile failed even after PortAudio install");
|
|
10065
10408
|
notificationService.error("naudiodon \u7F16\u8BD1\u5931\u8D25", "\u81EA\u52A8\u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u5C1D\u8BD5\u624B\u52A8\u5B89\u88C5", 8e3);
|
|
10066
10409
|
markNaudiodonSkipped();
|
|
10067
10410
|
}
|
|
10068
10411
|
} else {
|
|
10069
|
-
|
|
10412
|
+
logger9.error("PortAudio install failed");
|
|
10070
10413
|
notificationService.error("PortAudio \u5B89\u88C5\u5931\u8D25", "\u81EA\u52A8\u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u5C1D\u8BD5\u624B\u52A8\u5B89\u88C5", 8e3);
|
|
10071
10414
|
markNaudiodonSkipped();
|
|
10072
10415
|
}
|
|
@@ -10083,46 +10426,101 @@ function isModuleInstalled(moduleName) {
|
|
|
10083
10426
|
async function verifyModuleLoad(dep) {
|
|
10084
10427
|
try {
|
|
10085
10428
|
pluginRequire(dep);
|
|
10086
|
-
|
|
10429
|
+
logger9.info(`${dep} loaded successfully`);
|
|
10087
10430
|
return true;
|
|
10088
10431
|
} catch (err) {
|
|
10089
|
-
|
|
10432
|
+
logger9.warn({ err }, `${dep} load failed`);
|
|
10090
10433
|
return false;
|
|
10091
10434
|
}
|
|
10092
10435
|
}
|
|
10436
|
+
async function tryCompileSpeaker() {
|
|
10437
|
+
const dep = "speaker";
|
|
10438
|
+
const result = { success: false, stderr: "" };
|
|
10439
|
+
if (isModuleInstalled(dep)) {
|
|
10440
|
+
if (await verifyModuleLoad(dep)) {
|
|
10441
|
+
result.success = true;
|
|
10442
|
+
return result;
|
|
10443
|
+
}
|
|
10444
|
+
}
|
|
10445
|
+
if (!isModuleInstalled(dep)) {
|
|
10446
|
+
try {
|
|
10447
|
+
await execAsync("npm install speaker", opencodeNodeModules);
|
|
10448
|
+
} catch {
|
|
10449
|
+
}
|
|
10450
|
+
}
|
|
10451
|
+
try {
|
|
10452
|
+
await execAsync("npm rebuild speaker", opencodeNodeModules);
|
|
10453
|
+
if (await verifyModuleLoad(dep)) {
|
|
10454
|
+
result.success = true;
|
|
10455
|
+
}
|
|
10456
|
+
} catch (err) {
|
|
10457
|
+
result.stderr = err.stderr?.toString() || err.message || "";
|
|
10458
|
+
}
|
|
10459
|
+
return result;
|
|
10460
|
+
}
|
|
10461
|
+
async function ensureSpeakerCompiledAsync() {
|
|
10462
|
+
const compileResult = await tryCompileSpeaker();
|
|
10463
|
+
if (compileResult.success) {
|
|
10464
|
+
logger9.info("speaker compiled successfully");
|
|
10465
|
+
return;
|
|
10466
|
+
}
|
|
10467
|
+
const detectResult = detectMissingDependencies(compileResult.stderr);
|
|
10468
|
+
if (detectResult.missingHeaders.length === 0) {
|
|
10469
|
+
logger9.info("speaker compile failed with unknown error");
|
|
10470
|
+
return;
|
|
10471
|
+
}
|
|
10472
|
+
logger9.info({ missingHeaders: detectResult.missingHeaders }, "detected missing headers");
|
|
10473
|
+
const platformInfo = detectPlatform();
|
|
10474
|
+
const packages = mapHeadersToPackages(detectResult.missingHeaders, platformInfo.platform);
|
|
10475
|
+
if (packages.length === 0) {
|
|
10476
|
+
logger9.info("no known packages for missing headers");
|
|
10477
|
+
return;
|
|
10478
|
+
}
|
|
10479
|
+
logger9.info({ packages }, "mapped headers to packages, installing");
|
|
10480
|
+
await installSystemPackages(packages, notificationService);
|
|
10481
|
+
const retryResult = await tryCompileSpeaker();
|
|
10482
|
+
if (retryResult.success) {
|
|
10483
|
+
logger9.info("speaker compiled successfully after installing dependencies");
|
|
10484
|
+
} else {
|
|
10485
|
+
logger9.warn("speaker compile still failed after dependency installation");
|
|
10486
|
+
}
|
|
10487
|
+
}
|
|
10488
|
+
async function ensureSpeakerInstalledAsync() {
|
|
10489
|
+
await ensurePlaySoundInstalled();
|
|
10490
|
+
}
|
|
10491
|
+
async function initAsync() {
|
|
10492
|
+
setTimeout(async () => {
|
|
10493
|
+
await ensureSpeakerCompiledAsync();
|
|
10494
|
+
await ensureSpeakerInstalledAsync();
|
|
10495
|
+
}, 100);
|
|
10496
|
+
}
|
|
10093
10497
|
async function ensureSpeakerCompiled(maxRetries = 5) {
|
|
10094
10498
|
const dep = "speaker";
|
|
10095
10499
|
if (isModuleInstalled(dep)) {
|
|
10096
|
-
|
|
10500
|
+
logger9.info("speaker already installed");
|
|
10097
10501
|
if (await verifyModuleLoad(dep)) {
|
|
10098
10502
|
return;
|
|
10099
10503
|
}
|
|
10100
|
-
|
|
10504
|
+
logger9.info("speaker installed but not loadable, rebuilding");
|
|
10101
10505
|
notificationService.info("\u6B63\u5728\u7F16\u8BD1 speaker...", "Ocosay \u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10102
10506
|
try {
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
stdio: "inherit"
|
|
10106
|
-
});
|
|
10107
|
-
logger8.info("speaker rebuilt");
|
|
10507
|
+
await execAsync("npm rebuild speaker", opencodeNodeModules);
|
|
10508
|
+
logger9.info("speaker rebuilt");
|
|
10108
10509
|
} catch (err) {
|
|
10109
|
-
|
|
10510
|
+
logger9.warn({ err }, "speaker rebuild failed");
|
|
10110
10511
|
}
|
|
10111
10512
|
if (await verifyModuleLoad(dep)) {
|
|
10112
10513
|
notificationService.success("speaker \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
10113
10514
|
return;
|
|
10114
10515
|
}
|
|
10115
10516
|
} else {
|
|
10116
|
-
|
|
10517
|
+
logger9.info("speaker not found, installing");
|
|
10117
10518
|
notificationService.info("\u6B63\u5728\u5B89\u88C5 speaker...", "Ocosay \u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10118
10519
|
try {
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
stdio: "inherit"
|
|
10122
|
-
});
|
|
10123
|
-
logger8.info("speaker installed");
|
|
10520
|
+
await execAsync("npm install speaker", opencodeNodeModules);
|
|
10521
|
+
logger9.info("speaker installed");
|
|
10124
10522
|
} catch (err) {
|
|
10125
|
-
|
|
10523
|
+
logger9.warn({ err }, "speaker install failed");
|
|
10126
10524
|
}
|
|
10127
10525
|
}
|
|
10128
10526
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
@@ -10130,16 +10528,13 @@ async function ensureSpeakerCompiled(maxRetries = 5) {
|
|
|
10130
10528
|
notificationService.success("speaker \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
10131
10529
|
return;
|
|
10132
10530
|
}
|
|
10133
|
-
|
|
10531
|
+
logger9.info({ attempt, dep }, "speaker not loadable, trying rebuild");
|
|
10134
10532
|
notificationService.info(`\u6B63\u5728\u91CD\u65B0\u7F16\u8BD1 speaker (${attempt + 1}/${maxRetries})...`, "Ocosay", 3e3);
|
|
10135
10533
|
try {
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
stdio: "inherit"
|
|
10139
|
-
});
|
|
10140
|
-
logger8.info("speaker rebuilt");
|
|
10534
|
+
await execAsync("npm rebuild speaker", opencodeNodeModules);
|
|
10535
|
+
logger9.info("speaker rebuilt");
|
|
10141
10536
|
} catch (err) {
|
|
10142
|
-
|
|
10537
|
+
logger9.warn({ err }, "speaker rebuild failed");
|
|
10143
10538
|
}
|
|
10144
10539
|
if (await verifyModuleLoad(dep)) {
|
|
10145
10540
|
notificationService.success("speaker \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA", 5e3);
|
|
@@ -10149,27 +10544,24 @@ async function ensureSpeakerCompiled(maxRetries = 5) {
|
|
|
10149
10544
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
10150
10545
|
}
|
|
10151
10546
|
}
|
|
10152
|
-
|
|
10547
|
+
logger9.error({ dep }, "speaker could not be compiled");
|
|
10153
10548
|
notificationService.error("speaker \u7F16\u8BD1\u5931\u8D25", "\u8BF7\u624B\u52A8\u8FD0\u884C: npm install speaker && npm rebuild speaker", 8e3);
|
|
10154
10549
|
}
|
|
10155
10550
|
async function ensurePlaySoundInstalled() {
|
|
10156
10551
|
const dep = "play-sound";
|
|
10157
10552
|
if (isModuleInstalled(dep)) {
|
|
10158
|
-
|
|
10553
|
+
logger9.info("play-sound already installed");
|
|
10159
10554
|
if (await verifyModuleLoad(dep)) {
|
|
10160
10555
|
return;
|
|
10161
10556
|
}
|
|
10162
10557
|
}
|
|
10163
|
-
|
|
10558
|
+
logger9.info("play-sound not found, installing");
|
|
10164
10559
|
notificationService.info("\u6B63\u5728\u5B89\u88C5 play-sound...", "Ocosay \u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10165
10560
|
try {
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
stdio: "inherit"
|
|
10169
|
-
});
|
|
10170
|
-
logger8.info("play-sound installed");
|
|
10561
|
+
await execAsync("npm install play-sound", opencodeNodeModules);
|
|
10562
|
+
logger9.info("play-sound installed");
|
|
10171
10563
|
} catch (err) {
|
|
10172
|
-
|
|
10564
|
+
logger9.warn({ err }, "play-sound install failed");
|
|
10173
10565
|
notificationService.warning(
|
|
10174
10566
|
"play-sound \u5B89\u88C5\u5931\u8D25",
|
|
10175
10567
|
"\u8BF7\u624B\u52A8\u8FD0\u884C: npm install play-sound",
|
|
@@ -10193,7 +10585,7 @@ async function ensureOptionalDepsInstalled() {
|
|
|
10193
10585
|
}
|
|
10194
10586
|
function execCmd2(cmd) {
|
|
10195
10587
|
try {
|
|
10196
|
-
const output =
|
|
10588
|
+
const output = execSync4(cmd, { stdio: "pipe", encoding: "utf8" });
|
|
10197
10589
|
return { success: true, output };
|
|
10198
10590
|
} catch (err) {
|
|
10199
10591
|
return { success: false, output: err.message || "" };
|
|
@@ -10202,7 +10594,7 @@ function execCmd2(cmd) {
|
|
|
10202
10594
|
function isWsl2() {
|
|
10203
10595
|
if (process.platform !== "linux") return false;
|
|
10204
10596
|
try {
|
|
10205
|
-
return
|
|
10597
|
+
return require3("fs").readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft");
|
|
10206
10598
|
} catch {
|
|
10207
10599
|
return false;
|
|
10208
10600
|
}
|
|
@@ -10239,12 +10631,12 @@ async function checkAudioEnvironmentForBackend() {
|
|
|
10239
10631
|
async function installPortAudio() {
|
|
10240
10632
|
const platform = process.platform;
|
|
10241
10633
|
const wsl = isWsl2();
|
|
10242
|
-
|
|
10634
|
+
logger9.info({ platform, wsl }, "installing PortAudio");
|
|
10243
10635
|
const runInstall = async (cmd, desc) => {
|
|
10244
|
-
|
|
10636
|
+
logger9.info(`Running: ${cmd}`);
|
|
10245
10637
|
notificationService.info(desc, "\u6B63\u5728\u5B89\u88C5...", 5e3);
|
|
10246
10638
|
try {
|
|
10247
|
-
|
|
10639
|
+
await execAsync(cmd);
|
|
10248
10640
|
return true;
|
|
10249
10641
|
} catch (err) {
|
|
10250
10642
|
const msg = err.message || "";
|
|
@@ -10254,15 +10646,15 @@ async function installPortAudio() {
|
|
|
10254
10646
|
"# \u8BF7\u5728WSL\u7EC8\u7AEF\u6267\u884C\u4E00\u6B21\nsudo visudo\n# \u6DFB\u52A0\u884C\uFF1Ayour user name ALL=(ALL) NOPASSWD: ALL",
|
|
10255
10647
|
1e4
|
|
10256
10648
|
);
|
|
10257
|
-
|
|
10649
|
+
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");
|
|
10258
10650
|
return false;
|
|
10259
10651
|
}
|
|
10260
10652
|
if (msg.includes("already") || msg.includes("is already")) {
|
|
10261
|
-
|
|
10653
|
+
logger9.info("already installed");
|
|
10262
10654
|
return true;
|
|
10263
10655
|
}
|
|
10264
10656
|
notificationService.error(desc + " \u5931\u8D25", msg.substring(0, 100), 8e3);
|
|
10265
|
-
|
|
10657
|
+
logger9.error({ err }, `install failed: ${desc}`);
|
|
10266
10658
|
return false;
|
|
10267
10659
|
}
|
|
10268
10660
|
};
|
|
@@ -10270,7 +10662,7 @@ async function installPortAudio() {
|
|
|
10270
10662
|
notificationService.info("\u68C0\u6D4B ffmpeg...", "\u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10271
10663
|
const ffmpegCheck = execCmd2("which ffplay");
|
|
10272
10664
|
if (ffmpegCheck.success) {
|
|
10273
|
-
|
|
10665
|
+
logger9.info("ffmpeg already available");
|
|
10274
10666
|
notificationService.success("ffmpeg \u5C31\u7EEA", "ffplay \u53EF\u7528\u4E8E\u65E0\u58F0\u5361\u64AD\u653E", 5e3);
|
|
10275
10667
|
} else {
|
|
10276
10668
|
notificationService.info("\u5B89\u88C5 ffmpeg...", "\u97F3\u9891\u540E\u7AEF", 5e3);
|
|
@@ -10286,7 +10678,7 @@ async function installPortAudio() {
|
|
|
10286
10678
|
}
|
|
10287
10679
|
notificationService.info("\u68C0\u6D4B\u97F3\u9891\u8BBE\u5907...", "\u97F3\u9891\u540E\u7AEF", 5e3);
|
|
10288
10680
|
if (checkAlsa()) {
|
|
10289
|
-
|
|
10681
|
+
logger9.info("alsa-utils already available and working");
|
|
10290
10682
|
notificationService.success("alsa-utils \u5C31\u7EEA", "\u97F3\u9891\u540E\u7AEF\u5DF2\u53EF\u7528", 5e3);
|
|
10291
10683
|
return { success: true, message: "alsa" };
|
|
10292
10684
|
}
|
|
@@ -10477,8 +10869,9 @@ var server = (async (input, _options) => {
|
|
|
10477
10869
|
});
|
|
10478
10870
|
} catch (err) {
|
|
10479
10871
|
initError = err instanceof Error ? err : new Error(String(err));
|
|
10480
|
-
|
|
10872
|
+
logger9.error({ error: initError }, "initialization failed");
|
|
10481
10873
|
}
|
|
10874
|
+
initAsync();
|
|
10482
10875
|
await ensureNaudiodonCompiled();
|
|
10483
10876
|
await ensureOptionalDepsInstalled();
|
|
10484
10877
|
await checkAudioEnvironmentForBackend();
|