mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-04 04:04: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
9a20f0d1b0
commit
1499445762
2 changed files with 118 additions and 27 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
import { spawn } from 'child_process';
|
import { spawn } from 'child_process';
|
||||||
import type { ChildProcess } from 'child_process';
|
import type { ChildProcess } from 'child_process';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import { homedir } from 'os';
|
||||||
|
import { access } from 'fs/promises';
|
||||||
|
|
||||||
import { LogManager } from './LogManager';
|
import { LogManager } from './LogManager';
|
||||||
import { WindowManager } from './WindowManager';
|
import { WindowManager } from './WindowManager';
|
||||||
|
|
@ -53,6 +55,26 @@ export class OpenWebUIManager {
|
||||||
> {
|
> {
|
||||||
const env = { ...process.env };
|
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') {
|
if (process.platform === 'win32') {
|
||||||
env.PYTHONIOENCODING = 'utf-8';
|
env.PYTHONIOENCODING = 'utf-8';
|
||||||
env.PYTHONLEGACYWINDOWSSTDIO = '1';
|
env.PYTHONLEGACYWINDOWSSTDIO = '1';
|
||||||
|
|
@ -66,11 +88,7 @@ export class OpenWebUIManager {
|
||||||
async isUvAvailable(): Promise<boolean> {
|
async isUvAvailable(): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const env = await this.getUvEnvironment();
|
const env = await this.getUvEnvironment();
|
||||||
const testProcess = spawn('uv', ['--version'], {
|
const testProcess = spawn('uv', ['--version'], { stdio: 'pipe', env });
|
||||||
stdio: 'pipe',
|
|
||||||
env,
|
|
||||||
shell: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Promise<boolean>((resolve) => {
|
return new Promise<boolean>((resolve) => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
|
|
@ -109,7 +127,6 @@ export class OpenWebUIManager {
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
detached: false,
|
detached: false,
|
||||||
env: mergedEnv,
|
env: mergedEnv,
|
||||||
shell: true,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,24 +135,14 @@ export class OpenWebUIManager {
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const checkForOutput = (data: Buffer) => {
|
const checkForOutput = (data: Buffer) => {
|
||||||
try {
|
const output = data.toString();
|
||||||
const output = data.toString('utf8');
|
if (output.includes(SERVER_READY_SIGNALS.OPENWEBUI)) {
|
||||||
if (output.includes(SERVER_READY_SIGNALS.OPENWEBUI)) {
|
this.windowManager.sendKoboldOutput('Open WebUI is now running!');
|
||||||
this.windowManager.sendKoboldOutput('Open WebUI is now running!');
|
resolve();
|
||||||
resolve();
|
|
||||||
|
|
||||||
if (this.openWebUIProcess?.stdout) {
|
if (this.openWebUIProcess?.stdout) {
|
||||||
this.openWebUIProcess.stdout.removeListener(
|
this.openWebUIProcess.stdout.removeListener('data', checkForOutput);
|
||||||
'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 { createServer, request, type Server } from 'http';
|
||||||
import { homedir } from 'os';
|
import { homedir } from 'os';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import { access, readdir } from 'fs/promises';
|
||||||
import type { ChildProcess } from 'child_process';
|
import type { ChildProcess } from 'child_process';
|
||||||
|
|
||||||
import { LogManager } from './LogManager';
|
import { LogManager } from './LogManager';
|
||||||
|
|
@ -86,12 +87,94 @@ export class SillyTavernManager {
|
||||||
return join(dataRoot, 'default-user', 'settings.json');
|
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> {
|
async isNpxAvailable(): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const testProcess = spawn('npx', ['--version'], {
|
const env = await this.getNodeEnvironment();
|
||||||
stdio: 'pipe',
|
const testProcess = spawn('npx', ['--version'], { stdio: 'pipe', env });
|
||||||
shell: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Promise<boolean>((resolve) => {
|
return new Promise<boolean>((resolve) => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
|
|
@ -115,10 +198,11 @@ export class SillyTavernManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createNpxProcess(args: string[]): Promise<ChildProcess> {
|
private async createNpxProcess(args: string[]): Promise<ChildProcess> {
|
||||||
|
const env = await this.getNodeEnvironment();
|
||||||
return spawn('npx', args, {
|
return spawn('npx', args, {
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
detached: false,
|
detached: false,
|
||||||
shell: true,
|
env,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue