Firecracker microVM-based multi-agent system with IRC orchestration and local LLMs. Features: - Ephemeral command runner with VM snapshots (~1.1s) - Multi-agent orchestration via overseer IRC bot - 5 agent templates (worker, coder, researcher, quick, creative) - Tool access (shell + podman containers inside VMs) - Persistent workspace + memory system (MEMORY.md pattern) - Agent hot-reload (model/persona swap via SSH + SIGHUP) - Non-root agents, graceful shutdown, crash recovery - Agent-to-agent communication via IRC - DM support, /invite support - Systemd service, 20 regression tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
48 lines
1.1 KiB
TypeScript
48 lines
1.1 KiB
TypeScript
import type { VMInstance } from "./vm.js";
|
|
|
|
const activeVms = new Set<VMInstance>();
|
|
|
|
export function registerVm(vm: VMInstance) {
|
|
activeVms.add(vm);
|
|
}
|
|
|
|
export function unregisterVm(vm: VMInstance) {
|
|
activeVms.delete(vm);
|
|
}
|
|
|
|
async function cleanupAll() {
|
|
const vms = Array.from(activeVms);
|
|
activeVms.clear();
|
|
await Promise.allSettled(vms.map((vm) => vm.destroy()));
|
|
}
|
|
|
|
let registered = false;
|
|
|
|
export function installSignalHandlers() {
|
|
if (registered) return;
|
|
registered = true;
|
|
|
|
const handler = async (signal: string) => {
|
|
process.stderr.write(`\n[fireclaw] Caught ${signal}, cleaning up...\n`);
|
|
await cleanupAll();
|
|
process.exit(signal === "SIGINT" ? 130 : 143);
|
|
};
|
|
|
|
process.on("SIGINT", () => handler("SIGINT"));
|
|
process.on("SIGTERM", () => handler("SIGTERM"));
|
|
|
|
process.on("uncaughtException", async (err) => {
|
|
process.stderr.write(`[fireclaw] Uncaught exception: ${err.message}\n`);
|
|
await cleanupAll();
|
|
process.exit(1);
|
|
});
|
|
|
|
process.on("unhandledRejection", async (reason) => {
|
|
process.stderr.write(
|
|
`[fireclaw] Unhandled rejection: ${reason}\n`
|
|
);
|
|
await cleanupAll();
|
|
process.exit(1);
|
|
});
|
|
}
|