From 2bf2fd6c3d13fede007f3e98f275bc0f20b7bfb0 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 25 Apr 2026 08:44:53 +0530 Subject: [PATCH] fix(cli): preserve gateway status rpc probe semantics --- src/cli/command-catalog.ts | 4 ---- src/cli/daemon-cli/probe.ts | 29 ++++++++++++++++++++--------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/cli/command-catalog.ts b/src/cli/command-catalog.ts index c58f8b86209..fb471a7328c 100644 --- a/src/cli/command-catalog.ts +++ b/src/cli/command-catalog.ts @@ -57,10 +57,6 @@ export const cliCommandCatalog: readonly CliCommandCatalogEntry[] = [ exact: true, policy: { routeConfigGuard: "always", - // `gateway status` is a built-in daemon/RPC health path. Loading the - // full plugin registry here eagerly scans and validates every channel - // plugin before the command can even connect to the already-running - // gateway, which makes this frequently-used status check painfully slow. loadPlugins: "never", }, route: { id: "gateway-status" }, diff --git a/src/cli/daemon-cli/probe.ts b/src/cli/daemon-cli/probe.ts index 455addcd67c..486d02c93a9 100644 --- a/src/cli/daemon-cli/probe.ts +++ b/src/cli/daemon-cli/probe.ts @@ -43,7 +43,7 @@ export async function probeGatewayStatus(opts: { }, async () => { const { probeGateway } = await loadProbeGatewayModule(); - const probe = await probeGateway({ + const probeOpts = { url: opts.url, auth: { token: opts.token, @@ -51,13 +51,26 @@ export async function probeGatewayStatus(opts: { }, tlsFingerprint: opts.tlsFingerprint, timeoutMs: opts.timeoutMs, - includeDetails: opts.requireRpc === true, - detailLevel: opts.requireRpc === true ? "full" : "none", - }); - return probe; + includeDetails: false, + }; + if (opts.requireRpc) { + const { callGateway } = await import("../../gateway/call.js"); + await callGateway({ + url: opts.url, + token: opts.token, + password: opts.password, + tlsFingerprint: opts.tlsFingerprint, + method: "status", + timeoutMs: opts.timeoutMs, + ...(opts.configPath ? { configPath: opts.configPath } : {}), + }); + const authProbe = await probeGateway(probeOpts).catch(() => null); + return { ok: true as const, authProbe }; + } + return await probeGateway(probeOpts); }, ); - const auth = result.auth; + const auth = "auth" in result ? result.auth : result.authProbe?.auth; if (result.ok) { return { ok: true, @@ -66,9 +79,7 @@ export async function probeGatewayStatus(opts: { kind === "read" ? auth?.capability && auth.capability !== "unknown" ? auth.capability - : // A successful detailed probe performs read RPCs, so it proves read access - // even when hello metadata cannot recover richer scope metadata. - "read_only" + : "read_only" : auth?.capability, auth, } as const;