Added custom json edit to config tab

This commit is contained in:
Richard Osborne
2026-01-08 13:27:38 +01:00
parent 4a1080d547
commit 67b8ddc9c3
53 changed files with 8756 additions and 210 deletions

View File

@@ -1,9 +1,61 @@
import { exec } from 'child_process';
import { exec, ChildProcess, execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
import { ConsoleColor, attachStdio } from './utils/process';
// Track all spawned processes for cleanup
const childProcesses: ChildProcess[] = [];
/**
* Kills a process and all its children (the entire process tree).
* This is crucial for webpack/node processes that spawn child processes.
*/
function killProcessTree(proc: ChildProcess): void {
if (!proc.pid) return;
try {
if (process.platform === 'win32') {
// Windows: use taskkill with /T flag to kill tree
execSync(`taskkill /pid ${proc.pid} /T /F`, { stdio: 'ignore' });
} else {
// macOS/Linux: kill the entire process group
// Try to kill the process group (negative PID)
try {
process.kill(-proc.pid, 'SIGTERM');
} catch {
// If process group kill fails, try direct kill
proc.kill('SIGTERM');
}
}
} catch (error) {
// Process might already be dead - that's okay
}
}
/**
* Cleanup function that kills all child processes
*/
function cleanup(): void {
console.log('\n🧹 Cleaning up child processes...');
for (const proc of childProcesses) {
killProcessTree(proc);
}
// Also kill any lingering webpack processes from this session
try {
if (process.platform !== 'win32') {
// Kill any webpack processes that might be orphaned
execSync('pkill -f "webpack.*noodl" 2>/dev/null || true', { stdio: 'ignore' });
}
} catch {
// Ignore errors - processes might not exist
}
console.log('✅ Cleanup complete');
}
const CWD = path.join(__dirname, '..');
const LOCAL_GIT_DIRECTORY = path.join(__dirname, '..', 'node_modules', 'dugite', 'git');
const LOCAL_GIT_TRAMPOLINE_DIRECTORY = path.join(
@@ -65,6 +117,7 @@ const viewerProcess = attachStdio(
color: ConsoleColor.FgMagenta
}
);
childProcesses.push(viewerProcess);
const cloudRuntimeProcess = attachStdio(
exec(`npx lerna exec --scope @noodl/cloud-runtime -- npm run ${viewerScript}`, processOptions),
@@ -73,16 +126,39 @@ const cloudRuntimeProcess = attachStdio(
color: ConsoleColor.FgMagenta
}
);
childProcesses.push(cloudRuntimeProcess);
const editorProcess = attachStdio(exec('npx lerna exec --scope noodl-editor -- npm run start', processOptions), {
prefix: 'Editor',
color: ConsoleColor.FgCyan
});
childProcesses.push(editorProcess);
// Handle editor exit - cleanup and exit
editorProcess.on('exit', (code) => {
if (typeof code === 'number') {
viewerProcess.kill(0);
cloudRuntimeProcess.kill(0);
cleanup();
process.exit(0);
}
});
// Handle Ctrl+C (SIGINT) - cleanup all processes
process.on('SIGINT', () => {
console.log('\n\n⚠ Received SIGINT (Ctrl+C)');
cleanup();
process.exit(0);
});
// Handle SIGTERM - cleanup all processes
process.on('SIGTERM', () => {
console.log('\n\n⚠ Received SIGTERM');
cleanup();
process.exit(0);
});
// Handle uncaught exceptions - still try to cleanup
process.on('uncaughtException', (err) => {
console.error('\n\n❌ Uncaught exception:', err);
cleanup();
process.exit(1);
});