Implement agent runtime services and WebSocket realtime

Expand heartbeat service with full run executor, wakeup coordinator,
and adapter lifecycle. Add run-log-store for pluggable log persistence.
Add live-events service and WebSocket handler for realtime updates.
Expand agent and issue routes with runtime operations. Add ws dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-02-17 12:24:43 -06:00
parent 2583bf4c43
commit c9c75bbc0a
11 changed files with 1746 additions and 156 deletions

View File

@@ -1,7 +1,11 @@
import { createServer } from "node:http";
import { resolve } from "node:path";
import { createDb, createPgliteDb } from "@paperclip/db";
import { createApp } from "./app.js";
import { loadConfig } from "./config.js";
import { logger } from "./middleware/logger.js";
import { setupLiveEventsWebSocketServer } from "./realtime/live-events-ws.js";
import { heartbeatService } from "./services/index.js";
const config = loadConfig();
@@ -9,13 +13,33 @@ let db;
if (config.databaseUrl) {
db = createDb(config.databaseUrl);
} else {
logger.info("No DATABASE_URL set — using embedded PGlite (./data/pglite)");
db = await createPgliteDb("./data/pglite");
const dataDir = resolve("./data/pglite");
logger.info(`No DATABASE_URL set — using embedded PGlite (${dataDir})`);
db = await createPgliteDb(dataDir);
logger.info("PGlite ready, schema pushed");
}
const app = createApp(db as any, { serveUi: config.serveUi });
const server = createServer(app);
app.listen(config.port, () => {
setupLiveEventsWebSocketServer(server, db as any);
if (config.heartbeatSchedulerEnabled) {
const heartbeat = heartbeatService(db as any);
setInterval(() => {
void heartbeat
.tickTimers(new Date())
.then((result) => {
if (result.enqueued > 0) {
logger.info({ ...result }, "heartbeat timer tick enqueued runs");
}
})
.catch((err) => {
logger.error({ err }, "heartbeat timer tick failed");
});
}, config.heartbeatSchedulerIntervalMs);
}
server.listen(config.port, () => {
logger.info(`Server listening on :${config.port}`);
});