Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions src/commands/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,43 @@ async function verifyAuth(baseUrl: string, authToken: string | undefined): Promi
}
}

/** Check if the server is healthy at the given base URL. */
/** Check if the server is healthy at the given base URL.
* #3346: Also checks PID file as a fallback when the health endpoint times out.
* If the PID file exists and the process is alive, assume the server is running. */
async function isServerHealthy(baseUrl: string, authToken?: string): Promise<boolean> {
try {
const headers: Record<string, string> = {};
if (authToken) headers['Authorization'] = `Bearer ${authToken}`;
const res = await fetch(`${baseUrl}/v1/health`, { headers, signal: AbortSignal.timeout(3000) });
return res.ok;
if (res.ok) return true;
// Non-401 error or network issue — fall through to PID file check
} catch {
// Network error — fall through to PID file check
}

// #3346: Fallback — check if an Aegis server PID file exists with a live process
try {
const { existsSync, readFileSync } = await import('node:fs');
const stateDir = process.env.AEGIS_STATE_DIR || join(homedir(), '.aegis');
const pidFile = join(stateDir, 'aegis.pid');
if (existsSync(pidFile)) {
const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);
if (pid > 0 && pidExists(pid)) {
return true;
}
}
} catch {
// Ignore
}

return false;
}

/** Check if a process with the given PID is alive. */
function pidExists(pid: number): boolean {
try {
process.kill(pid, 0);
return true;
} catch {
return false;
}
Expand Down
Loading