mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
95 lines
2.4 KiB
TypeScript
95 lines
2.4 KiB
TypeScript
/* eslint-disable no-console */
|
|
import { spawn } from 'child_process';
|
|
import { platform, exit, stdout, stderr, stdin, on } from 'process';
|
|
|
|
import { terminateProcess } from '@/utils/node/process';
|
|
import { pathExists, readJsonFile } from '@/utils/node/fs';
|
|
import { getConfigDir } from '@/utils/node/path';
|
|
|
|
async function getCurrentKoboldBinary() {
|
|
try {
|
|
const configPath = getConfigDir();
|
|
if (!(await pathExists(configPath))) {
|
|
return null;
|
|
}
|
|
|
|
const config = await readJsonFile<{ currentKoboldBinary?: string }>(
|
|
configPath
|
|
);
|
|
return config?.currentKoboldBinary || null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function handleCliMode(args: string[]) {
|
|
const currentBinary = await getCurrentKoboldBinary();
|
|
|
|
if (!currentBinary) {
|
|
console.error(
|
|
'Error: No binary found. Please run the GUI first to download the binary.'
|
|
);
|
|
exit(1);
|
|
}
|
|
|
|
if (!(await pathExists(currentBinary))) {
|
|
console.error(`Error: Binary not found at: ${currentBinary}`);
|
|
console.error('Please run the GUI to download and configure the binary.');
|
|
exit(1);
|
|
}
|
|
|
|
return new Promise<void>((resolve, reject) => {
|
|
const isWindows = platform === 'win32';
|
|
|
|
const child = spawn(currentBinary, args, {
|
|
stdio: isWindows ? 'pipe' : 'inherit',
|
|
detached: false,
|
|
});
|
|
|
|
if (isWindows) {
|
|
child.stdout?.setEncoding('utf8');
|
|
child.stderr?.setEncoding('utf8');
|
|
|
|
child.stdout?.on('data', (data) => {
|
|
stdout.write(data.toString());
|
|
});
|
|
|
|
child.stderr?.on('data', (data) => {
|
|
stderr.write(data.toString());
|
|
});
|
|
|
|
if (child.stdin && stdin.readable) {
|
|
stdin.pipe(child.stdin);
|
|
}
|
|
}
|
|
|
|
child.on('exit', (code, signal) => {
|
|
if (signal) {
|
|
console.log(`\nProcess terminated with signal: ${signal}`);
|
|
exit(128 + (signal === 'SIGTERM' ? 15 : 2));
|
|
} else if (code !== null) {
|
|
exit(code);
|
|
} else {
|
|
resolve();
|
|
}
|
|
});
|
|
|
|
child.on('error', (error) => {
|
|
console.error(`Failed to start: ${error.message}`);
|
|
reject(error);
|
|
});
|
|
|
|
const handleSignal = async () => {
|
|
console.log('\nReceived termination signal, terminating...');
|
|
if (!child.killed) {
|
|
await terminateProcess(child);
|
|
}
|
|
};
|
|
|
|
on('SIGINT', handleSignal);
|
|
on('SIGTERM', handleSignal);
|
|
if (platform === 'win32') {
|
|
on('SIGBREAK', handleSignal);
|
|
}
|
|
});
|
|
}
|