worker: make/jq/gopls in base image + per-repo .lvmh/setup.sh hook (agent-driven persistent setup)

This commit is contained in:
Raphael Westphal
2026-08-18 17:38:38 +02:00
parent df91ba6c4c
commit 71ab821abd
5 changed files with 347 additions and 246 deletions
+38
View File
@@ -2,13 +2,51 @@
// at /root/.pi/agent/extensions/lvmh-agent.ts) dials the daemon and delivers
// web prompts through pi.sendUserMessage. This process just hosts the session.
// Global npm layout: resolve pi via absolute path (NODE_PATH does not apply to ESM).
import { spawn } from "node:child_process";
import { existsSync } from "node:fs";
import { createAgentSession } from "/usr/local/lib/node_modules/@earendil-works/pi-coding-agent/dist/index.js";
const SETUP_PATH = "/workspace/.lvmh/setup.sh";
const SETUP_TIMEOUT_MS = 10 * 60 * 1000;
// Repo-level setup hook: if the repo ships .lvmh/setup.sh, run it before the
// session starts (apt-get/go install/pip — anything the agent needs).
// /workspace is a persistent per-repo volume, so the hook survives container
// restarts and re-runs on every spawn. Failure is non-fatal: log and continue.
async function runRepoSetup() {
if (!existsSync(SETUP_PATH)) return;
console.error(`[lvmh-bridge] running repo setup: ${SETUP_PATH}`);
const code = await new Promise((resolve) => {
const child = spawn("bash", [SETUP_PATH], {
cwd: "/workspace",
stdio: ["ignore", "inherit", "inherit"],
});
const timer = setTimeout(() => {
console.error(`[lvmh-bridge] setup timed out after ${SETUP_TIMEOUT_MS}ms, killing`);
child.kill("SIGKILL");
resolve(124);
}, SETUP_TIMEOUT_MS);
timer.unref?.();
child.on("error", (err) => {
clearTimeout(timer);
console.error("[lvmh-bridge] setup spawn error:", err);
resolve(1);
});
child.on("exit", (c) => {
clearTimeout(timer);
resolve(c ?? 1);
});
});
if (code === 0) console.error("[lvmh-bridge] setup completed");
else console.error(`[lvmh-bridge] setup exited ${code} — continuing anyway`);
}
process.on("unhandledRejection", (err) => {
console.error("[lvmh-bridge] unhandledRejection:", err);
});
try {
await runRepoSetup();
const { session } = await createAgentSession();
// SDK does not bind extensions implicitly (unlike TUI/RPC modes); without
// bindExtensions the session_start event never fires, so the lvmh plugin