jlink-mcp
Version:
MCP server for SEGGER J-Link debug probes — LLM-driven embedded debugging with RTT, GDB server, and Trice/Pigweed support
70 lines • 2.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProcessManager = void 0;
const child_process_1 = require("child_process");
const logger_1 = require("./logger");
const events_1 = require("events");
/**
* Manages spawned child processes with lifecycle tracking.
*/
class ProcessManager extends events_1.EventEmitter {
processes = new Map();
spawn(name, command, args, options) {
// Kill existing process with same name
this.kill(name);
(0, logger_1.log)(`Spawning process "${name}": ${command} ${args.join(" ")}`);
const proc = (0, child_process_1.spawn)(command, args, {
stdio: ["pipe", "pipe", "pipe"],
...options,
});
const managed = {
process: proc,
name,
kill: () => this.kill(name),
};
proc.on("error", (err) => {
(0, logger_1.logError)(`Process "${name}" error`, err);
this.processes.delete(name);
this.emit("processExit", name, null, err);
});
proc.on("exit", (code, signal) => {
(0, logger_1.log)(`Process "${name}" exited (code=${code}, signal=${signal})`);
this.processes.delete(name);
this.emit("processExit", name, code, signal);
});
this.processes.set(name, managed);
return managed;
}
kill(name) {
const existing = this.processes.get(name);
if (existing) {
(0, logger_1.log)(`Killing process "${name}" (pid=${existing.process.pid})`);
existing.process.kill("SIGTERM");
// Force kill after 3 seconds
setTimeout(() => {
try {
existing.process.kill("SIGKILL");
}
catch {
// already dead
}
}, 3000);
this.processes.delete(name);
return true;
}
return false;
}
get(name) {
return this.processes.get(name);
}
killAll() {
for (const [name] of this.processes) {
this.kill(name);
}
}
listRunning() {
return Array.from(this.processes.keys());
}
}
exports.ProcessManager = ProcessManager;
//# sourceMappingURL=process-manager.js.map