fix(electrobun): sidecar runner path resolution for dev build output + debug logging
This commit is contained in:
parent
0eb4ba9396
commit
541b6eda46
1 changed files with 43 additions and 3 deletions
|
|
@ -3,9 +3,18 @@
|
|||
|
||||
import { join } from "path";
|
||||
import { homedir } from "os";
|
||||
import { existsSync } from "fs";
|
||||
import { existsSync, appendFileSync, mkdirSync } from "fs";
|
||||
import { parseMessage, type AgentMessage, type ProviderId } from "./message-adapter.ts";
|
||||
|
||||
// Debug log to file (always on in dev, check AGOR_DEBUG for prod)
|
||||
const DEBUG_LOG = join(homedir(), ".local", "share", "agor", "sidecar-debug.log");
|
||||
try { mkdirSync(join(homedir(), ".local", "share", "agor"), { recursive: true }); } catch {}
|
||||
function dbg(msg: string) {
|
||||
const line = `[${new Date().toISOString()}] ${msg}\n`;
|
||||
try { appendFileSync(DEBUG_LOG, line); } catch {}
|
||||
console.log(`[sidecar] ${msg}`);
|
||||
}
|
||||
|
||||
// ── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
export type SessionStatus = "running" | "idle" | "done" | "error";
|
||||
|
|
@ -111,8 +120,29 @@ function findClaudeCli(): string | undefined {
|
|||
// ── Runner resolution ────────────────────────────────────────────────────────
|
||||
|
||||
function resolveRunnerPath(provider: ProviderId): string {
|
||||
const repoRoot = join(import.meta.dir, "..", "..", "..");
|
||||
return join(repoRoot, "sidecar", "dist", `${provider}-runner.mjs`);
|
||||
// In dev mode, import.meta.dir is inside the Electrobun build output,
|
||||
// not the source tree. Walk up until we find sidecar/dist/ or use env var.
|
||||
const envRoot = process.env.AGOR_ROOT;
|
||||
if (envRoot) return join(envRoot, "sidecar", "dist", `${provider}-runner.mjs`);
|
||||
|
||||
// Try multiple candidate roots (dev build output vs source tree)
|
||||
const candidates = [
|
||||
join(import.meta.dir, "..", "..", ".."), // source: src/bun/ → repo root
|
||||
join(import.meta.dir, "..", "..", "..", "..", "..", ".."), // build: build/dev-linux-x64/App/... → repo root
|
||||
];
|
||||
|
||||
for (const root of candidates) {
|
||||
const path = join(root, "sidecar", "dist", `${provider}-runner.mjs`);
|
||||
if (existsSync(path)) {
|
||||
dbg(`Runner found at: ${path} (root: ${root})`);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: try finding from cwd
|
||||
const cwdPath = join(process.cwd(), "sidecar", "dist", `${provider}-runner.mjs`);
|
||||
dbg(`Trying cwd fallback: ${cwdPath}`);
|
||||
return cwdPath;
|
||||
}
|
||||
|
||||
function findNodeRuntime(): string {
|
||||
|
|
@ -175,12 +205,15 @@ export class SidecarManager {
|
|||
}
|
||||
|
||||
const runnerPath = resolveRunnerPath(provider);
|
||||
dbg(`startSession: id=${sessionId} provider=${provider} runner=${runnerPath}`);
|
||||
if (!existsSync(runnerPath)) {
|
||||
dbg(`ERROR: runner not found at ${runnerPath}`);
|
||||
return { ok: false, error: `Runner not found: ${runnerPath}` };
|
||||
}
|
||||
|
||||
const controller = new AbortController();
|
||||
const env = buildCleanEnv(options.extraEnv, options.claudeConfigDir);
|
||||
dbg(`Spawning: ${this.nodeRuntime} ${runnerPath} cwd=${options.cwd || 'default'}`);
|
||||
|
||||
const proc = Bun.spawn([this.nodeRuntime, runnerPath], {
|
||||
stdin: "pipe",
|
||||
|
|
@ -218,6 +251,7 @@ export class SidecarManager {
|
|||
|
||||
// Monitor process exit
|
||||
proc.exited.then((exitCode) => {
|
||||
dbg(`Process exited: session=${sessionId} code=${exitCode}`);
|
||||
const s = this.sessions.get(sessionId);
|
||||
if (s) {
|
||||
s.state.status = exitCode === 0 ? "done" : "error";
|
||||
|
|
@ -248,8 +282,10 @@ export class SidecarManager {
|
|||
queryMsg.worktreeName = options.worktreeName;
|
||||
}
|
||||
|
||||
dbg(`Sending query: ${JSON.stringify(queryMsg).slice(0, 200)}...`);
|
||||
this.writeToProcess(sessionId, queryMsg);
|
||||
|
||||
dbg(`Session ${sessionId} started successfully`);
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
|
|
@ -419,6 +455,7 @@ export class SidecarManager {
|
|||
const text = decoder.decode(chunk, { stream: true });
|
||||
for (const line of text.split("\n")) {
|
||||
if (line.trim()) {
|
||||
dbg(`STDERR [${sessionId}]: ${line.trim()}`);
|
||||
console.log(`[sidecar:${sessionId}] ${line.trim()}`);
|
||||
}
|
||||
}
|
||||
|
|
@ -429,16 +466,19 @@ export class SidecarManager {
|
|||
}
|
||||
|
||||
private handleNdjsonLine(sessionId: string, session: ActiveSession, line: string): void {
|
||||
dbg(`NDJSON [${sessionId}]: ${line.slice(0, 200)}`);
|
||||
let raw: Record<string, unknown>;
|
||||
try {
|
||||
raw = JSON.parse(line);
|
||||
} catch {
|
||||
dbg(`Invalid JSON from ${sessionId}: ${line.slice(0, 100)}`);
|
||||
console.warn(`[sidecar] Invalid JSON from ${sessionId}: ${line.slice(0, 100)}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle sidecar-level events (not forwarded to message adapter)
|
||||
const type = raw.type;
|
||||
dbg(`Event type: ${type} for ${sessionId}`);
|
||||
if (type === "ready" || type === "pong") return;
|
||||
|
||||
if (type === "agent_started") {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue