chore(telemetry): fix agent loops, name mangling, dev server leaks, CWD alignment, and add daily session auditor

This commit is contained in:
2026-06-08 16:09:58 -07:00
parent 0dc549ff37
commit 1f2fbd1115
6 changed files with 690 additions and 71 deletions

View File

@@ -803,20 +803,57 @@ export async function startDevServer(
// 2. Stop ALL tracked rows for this project on the target port.
// Previous runs may have crashed or exited without being marked
// stopped, causing stale rows to accumulate (15+ rows seen in
// prod). We reap them unconditionally before starting anything
// new — the AI's intent is "I want THIS command on THIS port",
// so most-recent-write-wins.
// stopped, causing stale rows to accumulate. We reap them
// unconditionally before starting anything new — the AI's intent
// is "I want THIS command on THIS port", so most-recent-write-wins.
const existingRows = await query<{ id: string; pid: number | null }>(
`SELECT id, pid FROM fs_dev_servers
WHERE project_id = $1 AND port = $2 AND state IN ('starting','running','failed')`,
[opts.projectId, opts.port],
);
const killPortNodeCmd =
`node -e '` +
`const fs = require("fs"); ` +
`const port = ${opts.port}; ` +
`try { ` +
`const hexPort = port.toString(16).toUpperCase().padStart(4, "0"); ` +
`const tcp = fs.readFileSync("/proc/net/tcp", "utf8"); ` +
`const inodes = []; ` +
`tcp.split("\\n").forEach(line => { ` +
`const parts = line.trim().split(/\\s+/); ` +
`if (parts.length > 9) { ` +
`const local = parts[1]; ` +
`if (local.endsWith(":" + hexPort)) { inodes.push(parts[9]); } ` +
`} ` +
`}); ` +
`if (inodes.length > 0) { ` +
`fs.readdirSync("/proc").forEach(file => { ` +
`if (/^\\d+$/.test(file)) { ` +
`try { ` +
`const fds = fs.readdirSync("/proc/" + file + "/fd"); ` +
`for (const fd of fds) { ` +
`const link = fs.readlinkSync("/proc/" + file + "/fd/" + fd); ` +
`for (const inode of inodes) { ` +
`if (link.includes("socket:[" + inode + "]")) { ` +
`process.kill(parseInt(file, 10), 9); ` +
`break; ` +
`} ` +
`} ` +
`} ` +
`} catch (e) {} ` +
`} ` +
`}); ` +
`} ` +
`} catch (e) { ` +
`try { require("child_process").execSync("fuser -k -9 ${opts.port}/tcp 2>/dev/null || true"); } catch (err) {} ` +
`}'`;
for (const row of existingRows) {
if (row.pid) {
await execInDevContainer({
projectId: opts.projectId,
command: `kill ${row.pid} 2>/dev/null || true`,
command: `kill -9 ${row.pid} 2>/dev/null || true`,
timeoutMs: 3_000,
}).catch(() => {});
}
@@ -826,44 +863,13 @@ export async function startDevServer(
);
}
// 3. Detect ANY listener on the requested port (including untracked
// processes from earlier manual runs). We use ss (ships in
// iproute2, default in Ubuntu base) because lsof isn't installed.
const portCheck = await execInDevContainer({
// 3. Force-kill ANY process currently listening on the port inside the container
// (including untracked orphans or processes from other runs).
await execInDevContainer({
projectId: opts.projectId,
command:
`ss -tlnp 2>/dev/null | grep ':${opts.port}\b' | head -1; ` +
`lsof -iTCP:${opts.port} -sTCP:LISTEN -n -P 2>/dev/null | tail -n +2 | head -1 || true`,
command: killPortNodeCmd,
timeoutMs: 5_000,
});
const listenerLine = portCheck.stdout.trim();
if (listenerLine) {
const pidMatch =
listenerLine.match(/pid=(\d+)/) || listenerLine.match(/^\S+\s+(\d+)/);
const listenerPid = pidMatch ? parseInt(pidMatch[1], 10) : null;
// Force-kill whatever is squatting on the port — we already
// reaped our tracked rows above, so this is an orphan.
if (listenerPid) {
await execInDevContainer({
projectId: opts.projectId,
command: `kill ${listenerPid} 2>/dev/null || true; sleep 0.5`,
timeoutMs: 5_000,
}).catch(() => {});
}
// Double-check the port is actually free now
const recheck = await execInDevContainer({
projectId: opts.projectId,
command: `ss -tlnp 2>/dev/null | grep ':${opts.port}\b' | head -1`,
timeoutMs: 3_000,
});
if (recheck.stdout.trim()) {
throw new PortBusyError(
opts.port,
listenerPid,
listenerLine.slice(0, 200),
);
}
}
}).catch(() => {});
// 3. Launch.
const id = `ds_${randomToken(6)}`;
@@ -876,7 +882,7 @@ export async function startDevServer(
const launch =
`mkdir -p /var/log/vibn-dev && ` +
`cd /workspace && ` +
`cd /workspace/${opts.projectSlug} && ` +
`nohup env PORT=${opts.port} VIBN_DEV_SERVER_ID=${id} ` +
`bash -lc ${shellEscape(listenSafeCommand)} > ${logFile} 2>&1 & ` +
`echo $!`;