diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index 641476e87..3ebb5532c 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -222,6 +222,10 @@ export class AgentRelayClient { }; } + get brokerPid(): number | undefined { + return this.child?.pid; + } + async start(): Promise { if (this.child) { return; diff --git a/src/cli/commands/core.ts b/src/cli/commands/core.ts index 5e33e504c..fd8dea0b8 100644 --- a/src/cli/commands/core.ts +++ b/src/cli/commands/core.ts @@ -76,6 +76,8 @@ export interface CoreRelay { onBrokerStderr?: (listener: (line: string) => void) => () => void; /** Relaycast workspace API key, available after the hello handshake. */ workspaceKey?: string; + /** PID of the underlying broker process, when available. */ + brokerPid?: number; } export interface CoreFileSystem { @@ -259,6 +261,7 @@ function createDefaultRelay(cwd: string, apiPort = 0): CoreRelay { shutdown: () => client.shutdown(), onBrokerStderr: (listener: (line: string) => void) => client.onBrokerStderr(listener), get workspaceKey() { return client.workspaceKey; }, + get brokerPid() { return client.brokerPid; }, }; return relay; } diff --git a/src/cli/lib/broker-lifecycle.ts b/src/cli/lib/broker-lifecycle.ts index ed31c211d..ab9fac6b9 100644 --- a/src/cli/lib/broker-lifecycle.ts +++ b/src/cli/lib/broker-lifecycle.ts @@ -173,9 +173,26 @@ function isProcessRunning(pid: number, deps: CoreDependencies): boolean { async function killOrphanedBrokerProcesses(projectRoot: string, deps: CoreDependencies): Promise { try { const shellQuote = (s: string): string => "'" + s.replace(/'/g, "'\\''") + "'"; - const { stdout } = await deps.execCommand( - `ps aux | grep '[a]gent-relay-broker' | grep -F ${shellQuote(projectRoot)}` - ); + const brokerName = path.basename(projectRoot) || 'project'; + let stdout = ''; + try { + const byName = await deps.execCommand( + `ps aux | grep '[a]gent-relay-broker' | grep -F ${shellQuote('--name ' + brokerName)}` + ); + stdout = byName.stdout; + } catch { + // Name filter may not match older process invocations; try legacy path-based filter. + } + if (!stdout.trim()) { + try { + const byPath = await deps.execCommand( + `ps aux | grep '[a]gent-relay-broker' | grep -F ${shellQuote(projectRoot)}` + ); + stdout = byPath.stdout; + } catch { + // Expected when no orphaned processes are matched by either strategy. + } + } const lines = stdout.trim().split('\n').filter(Boolean); for (const line of lines) { const parts = line.trim().split(/\s+/); @@ -882,7 +899,7 @@ export async function runUpCommand(options: UpOptions, deps: CoreDependencies): ); relay = started.relay; apiPort = started.apiPort; - writeBrokerPid(brokerPidPath, deps.pid, deps); + writeBrokerPid(brokerPidPath, relay.brokerPid ?? deps.pid, deps); const dashboardRelayUrl = resolveDashboardRelayUrl(apiPort, deps); const expectedRelayUrl = getDefaultDashboardRelayUrl(apiPort); if (