mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
need to revert the local path guessing is electron "shell: true" doesn't work as expected
This commit is contained in:
parent
ca4f5baa60
commit
5557738736
2 changed files with 118 additions and 27 deletions
|
|
@ -1,6 +1,8 @@
|
|||
import { spawn } from 'child_process';
|
||||
import type { ChildProcess } from 'child_process';
|
||||
import { join } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { access } from 'fs/promises';
|
||||
|
||||
import { LogManager } from './LogManager';
|
||||
import { WindowManager } from './WindowManager';
|
||||
|
|
@ -53,6 +55,26 @@ export class OpenWebUIManager {
|
|||
> {
|
||||
const env = { ...process.env };
|
||||
|
||||
const uvPaths = [
|
||||
join(homedir(), '.cargo', 'bin'),
|
||||
join(homedir(), '.local', 'bin'),
|
||||
];
|
||||
|
||||
const existingPaths: string[] = [];
|
||||
for (const path of uvPaths) {
|
||||
try {
|
||||
await access(path);
|
||||
existingPaths.push(path);
|
||||
} catch {
|
||||
void 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (existingPaths.length > 0) {
|
||||
const pathSeparator = process.platform === 'win32' ? ';' : ':';
|
||||
env.PATH = `${existingPaths.join(pathSeparator)}${pathSeparator}${env.PATH}`;
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
env.PYTHONIOENCODING = 'utf-8';
|
||||
env.PYTHONLEGACYWINDOWSSTDIO = '1';
|
||||
|
|
@ -66,11 +88,7 @@ export class OpenWebUIManager {
|
|||
async isUvAvailable(): Promise<boolean> {
|
||||
try {
|
||||
const env = await this.getUvEnvironment();
|
||||
const testProcess = spawn('uv', ['--version'], {
|
||||
stdio: 'pipe',
|
||||
env,
|
||||
shell: true,
|
||||
});
|
||||
const testProcess = spawn('uv', ['--version'], { stdio: 'pipe', env });
|
||||
|
||||
return new Promise<boolean>((resolve) => {
|
||||
const timeout = setTimeout(() => {
|
||||
|
|
@ -109,7 +127,6 @@ export class OpenWebUIManager {
|
|||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
detached: false,
|
||||
env: mergedEnv,
|
||||
shell: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -118,24 +135,14 @@ export class OpenWebUIManager {
|
|||
|
||||
return new Promise((resolve, reject) => {
|
||||
const checkForOutput = (data: Buffer) => {
|
||||
try {
|
||||
const output = data.toString('utf8');
|
||||
if (output.includes(SERVER_READY_SIGNALS.OPENWEBUI)) {
|
||||
this.windowManager.sendKoboldOutput('Open WebUI is now running!');
|
||||
resolve();
|
||||
const output = data.toString();
|
||||
if (output.includes(SERVER_READY_SIGNALS.OPENWEBUI)) {
|
||||
this.windowManager.sendKoboldOutput('Open WebUI is now running!');
|
||||
resolve();
|
||||
|
||||
if (this.openWebUIProcess?.stdout) {
|
||||
this.openWebUIProcess.stdout.removeListener(
|
||||
'data',
|
||||
checkForOutput
|
||||
);
|
||||
}
|
||||
if (this.openWebUIProcess?.stdout) {
|
||||
this.openWebUIProcess.stdout.removeListener('data', checkForOutput);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logManager.logError(
|
||||
'Error checking OpenWebUI output:',
|
||||
error as Error
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { spawn } from 'child_process';
|
|||
import { createServer, request, type Server } from 'http';
|
||||
import { homedir } from 'os';
|
||||
import { join } from 'path';
|
||||
import { access, readdir } from 'fs/promises';
|
||||
import type { ChildProcess } from 'child_process';
|
||||
|
||||
import { LogManager } from './LogManager';
|
||||
|
|
@ -86,12 +87,94 @@ export class SillyTavernManager {
|
|||
return join(dataRoot, 'default-user', 'settings.json');
|
||||
}
|
||||
|
||||
private async tryAddPathToEnv(
|
||||
env: Record<string, string | undefined>,
|
||||
path: string
|
||||
): Promise<boolean> {
|
||||
const pathSeparator = process.platform === 'win32' ? ';' : ':';
|
||||
if (!env.PATH?.includes(path)) {
|
||||
env.PATH = `${path}${pathSeparator}${env.PATH}`;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async tryVersionManagerPath(
|
||||
basePath: string,
|
||||
env: Record<string, string | undefined>
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
await access(basePath);
|
||||
const versions = await readdir(basePath);
|
||||
if (versions.length > 0) {
|
||||
const latestVersion = versions.sort().pop();
|
||||
if (latestVersion) {
|
||||
const binSubPath = basePath.includes('fnm')
|
||||
? join('installation', 'bin')
|
||||
: 'bin';
|
||||
const nodeBinPath = join(basePath, latestVersion, binSubPath);
|
||||
|
||||
try {
|
||||
await access(nodeBinPath);
|
||||
return this.tryAddPathToEnv(env, nodeBinPath);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async getNodeEnvironment(): Promise<
|
||||
Record<string, string | undefined>
|
||||
> {
|
||||
const env = { ...process.env };
|
||||
|
||||
const versionManagerPaths = [
|
||||
join(homedir(), '.local', 'share', 'fnm', 'node-versions'),
|
||||
join(homedir(), '.nvm', 'versions', 'node'),
|
||||
join(homedir(), '.volta', 'tools', 'image', 'node'),
|
||||
join(homedir(), '.asdf', 'installs', 'nodejs'),
|
||||
];
|
||||
|
||||
const systemPaths: string[] = [];
|
||||
if (process.platform === 'darwin') {
|
||||
systemPaths.push('/opt/homebrew/bin', '/usr/local/bin');
|
||||
}
|
||||
if (process.platform === 'win32') {
|
||||
versionManagerPaths.push(
|
||||
join(homedir(), 'AppData', 'Local', 'fnm', 'node-versions'),
|
||||
join(homedir(), 'AppData', 'Roaming', 'nvm')
|
||||
);
|
||||
}
|
||||
|
||||
for (const systemPath of systemPaths) {
|
||||
try {
|
||||
await access(systemPath);
|
||||
if (await this.tryAddPathToEnv(env, systemPath)) {
|
||||
return env;
|
||||
}
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (const versionPath of versionManagerPaths) {
|
||||
if (await this.tryVersionManagerPath(versionPath, env)) {
|
||||
return env;
|
||||
}
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
async isNpxAvailable(): Promise<boolean> {
|
||||
try {
|
||||
const testProcess = spawn('npx', ['--version'], {
|
||||
stdio: 'pipe',
|
||||
shell: true,
|
||||
});
|
||||
const env = await this.getNodeEnvironment();
|
||||
const testProcess = spawn('npx', ['--version'], { stdio: 'pipe', env });
|
||||
|
||||
return new Promise<boolean>((resolve) => {
|
||||
const timeout = setTimeout(() => {
|
||||
|
|
@ -115,10 +198,11 @@ export class SillyTavernManager {
|
|||
}
|
||||
|
||||
private async createNpxProcess(args: string[]): Promise<ChildProcess> {
|
||||
const env = await this.getNodeEnvironment();
|
||||
return spawn('npx', args, {
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
detached: false,
|
||||
shell: true,
|
||||
env,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue