#!/usr/bin/env bun import { createWorkbenchHttpApp } from "../../internal/workbench/http.ts"; import { workbenchRuntime } from "../../internal/workbench/runtime.ts"; import { startHwlabKafkaEventBridge } from "../../internal/cloud/kafka-event-bridge.ts"; const runtime = workbenchRuntime(process.env, { eventPublisher: null }); const kafkaEventBridge = runtime.mode === "agentrun-native" ? startHwlabKafkaEventBridge({ env: process.env }) : null; const app = createWorkbenchHttpApp({ dispatch: runtime.dispatch, snapshot: runtime.application.snapshot?.bind(runtime.application), authorization: process.env.WORKBENCH_API_AUTHORIZATION, mode: runtime.mode, kafkaEventBridge, close: async () => { await kafkaEventBridge?.stop?.(); await runtime.close(); } }); const host = process.env.WORKBENCH_API_HOST || "0.0.0.0"; const port = positivePort(process.env.WORKBENCH_API_PORT || process.env.PORT, 6677); const idleTimeoutConfig = positiveIntegerOrDefault(process.env.WORKBENCH_API_IDLE_TIMEOUT_SECONDS, 60); const idleTimeout = idleTimeoutConfig.value; if (idleTimeoutConfig.warningReason) { process.stderr.write(`${JSON.stringify({ event: "hwlab.config.warning", code: "workbench_api_idle_timeout_defaulted", configKey: "WORKBENCH_API_IDLE_TIMEOUT_SECONDS", reason: idleTimeoutConfig.warningReason, defaultValue: idleTimeout, blocking: false, valuesPrinted: false })}\n`); } const server = Bun.serve({ hostname: host, port, idleTimeout, fetch: (request) => app.fetch(request) }); process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-workbench-api", status: "listening", mode: runtime.mode, host, port: server.port, idleTimeout, temporalNamespace: runtime.temporalNamespace, taskQueue: runtime.taskQueue })}\n`); for (const signal of ["SIGINT", "SIGTERM"] as const) process.once(signal, async () => { server.stop(true); await app.close(); process.exit(0); }); function positivePort(value: string | undefined, fallback: number) { const parsed = Number.parseInt(String(value ?? fallback), 10); if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) throw new Error("WORKBENCH_API_PORT must be a valid port"); return parsed; } function positiveIntegerOrDefault(value: string | undefined, fallback: number) { const raw = String(value ?? "").trim(); if (!raw) return { value: fallback, warningReason: "missing" }; const parsed = Number.parseInt(raw, 10); if (!Number.isSafeInteger(parsed) || parsed < 1 || String(parsed) !== raw) return { value: fallback, warningReason: "invalid-positive-integer" }; return { value: parsed, warningReason: null }; }