mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 14:40:43 +00:00
fix(nodes): allow removing stale paired nodes
This commit is contained in:
@@ -71,6 +71,30 @@ export function registerNodesPairingCommands(nodes: Command) {
|
||||
}),
|
||||
);
|
||||
|
||||
nodesCallOpts(
|
||||
nodes
|
||||
.command("remove")
|
||||
.description("Remove a paired node entry")
|
||||
.requiredOption("--node <idOrNameOrIp>", "Node id, name, or IP")
|
||||
.action(async (opts: NodesRpcOpts) => {
|
||||
await runNodesCommand("remove", async () => {
|
||||
const nodeId = await resolveNodeId(opts, normalizeOptionalString(opts.node) ?? "");
|
||||
if (!nodeId) {
|
||||
defaultRuntime.error("--node required");
|
||||
defaultRuntime.exit(1);
|
||||
return;
|
||||
}
|
||||
const result = await callGatewayCli("node.pair.remove", opts, { nodeId });
|
||||
if (opts.json) {
|
||||
defaultRuntime.writeJson(result);
|
||||
return;
|
||||
}
|
||||
const { warn } = getNodesTheme();
|
||||
defaultRuntime.log(warn(`Removed paired node ${nodeId}`));
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
nodesCallOpts(
|
||||
nodes
|
||||
.command("rename")
|
||||
|
||||
@@ -22,6 +22,7 @@ export function registerNodesCli(program: Command) {
|
||||
`\n${theme.heading("Examples:")}\n${formatHelpExamples([
|
||||
["openclaw nodes status", "List known nodes with live status."],
|
||||
["openclaw nodes pairing pending", "Show pending node pairing requests."],
|
||||
["openclaw nodes remove --node <id|name|ip>", "Remove a stale paired node entry."],
|
||||
[
|
||||
'openclaw nodes invoke --node <id> --command system.which --params \'{"name":"uname"}\'',
|
||||
"Invoke a node command directly.",
|
||||
|
||||
@@ -424,6 +424,35 @@ describe("cli program (nodes basics)", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("runs nodes remove and calls node.pair.remove", async () => {
|
||||
callGateway.mockImplementation(async (...args: unknown[]) => {
|
||||
const opts = (args[0] ?? {}) as { method?: string };
|
||||
if (opts.method === "node.list") {
|
||||
return {
|
||||
nodes: [{ nodeId: "ios-node", displayName: "iOS Node", paired: true }],
|
||||
};
|
||||
}
|
||||
if (opts.method === "node.pair.list") {
|
||||
return {
|
||||
pending: [],
|
||||
paired: [{ nodeId: "ios-node", displayName: "iOS Node" }],
|
||||
};
|
||||
}
|
||||
if (opts.method === "node.pair.remove") {
|
||||
return { nodeId: "ios-node" };
|
||||
}
|
||||
return { ok: true };
|
||||
});
|
||||
|
||||
await runProgram(["nodes", "remove", "--node", "iOS Node"]);
|
||||
expect(callGateway).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
method: "node.pair.remove",
|
||||
params: { nodeId: "ios-node" },
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("runs nodes invoke and calls node.invoke", async () => {
|
||||
mockGatewayWithIosNodeListAnd("node.invoke", {
|
||||
ok: true,
|
||||
|
||||
Reference in New Issue
Block a user