CLI: preserve nodes list pairing fallback

This commit is contained in:
LXT 2026-03-20 23:40:15 +08:00
parent e2602f6807
commit 7fc87c533b
2 changed files with 30 additions and 0 deletions

View File

@ -128,6 +128,7 @@ function shouldFallbackToPairList(error: unknown): boolean {
message.includes("unknown method") || message.includes("unknown method") ||
message.includes("method not found") || message.includes("method not found") ||
message.includes("invalid request") || message.includes("invalid request") ||
message.includes("missing scope: operator.read") ||
message.includes("not implemented") || message.includes("not implemented") ||
message.includes("unsupported") message.includes("unsupported")
); );

View File

@ -211,6 +211,35 @@ describe("cli program (nodes basics)", () => {
expect(output).toContain("One"); expect(output).toContain("One");
}); });
it("runs nodes list and falls back to node.pair.list on missing read scope", async () => {
callGateway.mockImplementation(async (...args: unknown[]) => {
const opts = (args[0] ?? {}) as { method?: string };
if (opts.method === "node.pair.list") {
return {
pending: [],
paired: [
{
nodeId: "n1",
displayName: "One",
remoteIp: "10.0.0.1",
lastConnectedAtMs: Date.now() - 1_000,
},
],
};
}
if (opts.method === "node.list") {
throw new Error("missing scope: operator.read");
}
return { ok: true };
});
await runProgram(["nodes", "list"]);
const output = getRuntimeOutput();
expect(output).toContain("Pending: 0 · Paired: 1");
expect(output).toContain("One");
});
it("fails clearly for nodes list --connected when node.list is unavailable", async () => { it("fails clearly for nodes list --connected when node.list is unavailable", async () => {
callGateway.mockImplementation(async (...args: unknown[]) => { callGateway.mockImplementation(async (...args: unknown[]) => {
const opts = (args[0] ?? {}) as { method?: string }; const opts = (args[0] ?? {}) as { method?: string };