Skip to content
Open
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
46 changes: 38 additions & 8 deletions src/lib/nodes/list.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { Command } from "@commander-js/extra-typings";
import { Command, Option } from "@commander-js/extra-typings";
import { brightBlack, gray } from "jsr:@std/fmt/colors";
import console from "node:console";
import ora from "ora";
Expand Down Expand Up @@ -32,6 +32,17 @@ dayjs.extend(utc);
dayjs.extend(advanced);
dayjs.extend(timezone);

// Valid node status values for filtering
const VALID_STATES = [
"pending",
"awaitingcapacity",
"running",
"released",
"failed",
"terminated",
"deleted",
] as const;

// Helper component to display VMs in a table format using Ink
function VMTable({ vms }: { vms: NonNullable<SFCNodes.Node["vms"]>["data"] }) {
const sortedVms = vms.sort((a, b) => b.updated_at - a.updated_at);
Expand Down Expand Up @@ -455,26 +466,32 @@ async function listNodesAction(options: ReturnType<typeof list.opts>) {

spinner.stop();

// Apply optional state filter if provided
const selectedStates = (options as unknown as { state?: string[] }).state;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Type assertion is unsafe. Consider adding proper type definition for options parameter or using type guards.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/nodes/list.tsx
Line: 470:470

Comment:
**style:** Type assertion is unsafe. Consider adding proper type definition for options parameter or using type guards.

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

const filteredNodes = Array.isArray(selectedStates) && selectedStates.length > 0
? nodes.filter((n) => selectedStates.includes(n.status))
: nodes;

if (options.json) {
console.log(JSON.stringify(nodes, null, 2));
console.log(JSON.stringify(filteredNodes, null, 2));
return;
}

if (nodes.length === 0) {
if (filteredNodes.length === 0) {
console.log("No nodes found.");
console.log(gray("\nCreate your first node:"));
console.log(" sf nodes create my-first-node");
return;
}

if (options.verbose) {
render(<NodesVerboseDisplay nodes={nodes} />);
render(<NodesVerboseDisplay nodes={filteredNodes} />);
} else {
console.log(createNodesTable(nodes));
console.log(createNodesTable(filteredNodes));
console.log(
gray(
`\nFound ${nodes.length} ${
pluralizeNodes(nodes.length)
`\nFound ${filteredNodes.length} ${
pluralizeNodes(filteredNodes.length)
}. Use --verbose for detailed information, such as previous virtual machines.`,
),
);
Expand All @@ -484,7 +501,7 @@ async function listNodesAction(options: ReturnType<typeof list.opts>) {
const seenLabels = new Set<string>();

// Sort nodes by created_at (newest first), fallback to index for consistent ordering
const sortedNodes = [...nodes].sort((a, b) => {
const sortedNodes = [...filteredNodes].sort((a, b) => {
const aTime = a.created_at || 0;
const bTime = b.created_at || 0;
return bTime - aTime; // Newest first
Expand Down Expand Up @@ -521,6 +538,16 @@ const list = new Command("list")
.description("List all compute nodes")
.showHelpAfterError()
.option("--verbose", "Show detailed information for each node")
.addOption(
new Option("--state <state>", "Filter by node status")
.choices([...VALID_STATES] as unknown as string[])
.argParser((value: (typeof VALID_STATES)[number], previous?: string[]) => {
const acc = previous ?? [];
acc.push(value);
return acc;
})
.default([] as string[]),
)
.addOption(jsonOption)
.addHelpText(
"after",
Expand All @@ -532,6 +559,9 @@ Next Steps:\n
\x1b[2m# List all nodes with detailed information\x1b[0m
$ sf nodes list --verbose

\x1b[2m# List pending or running nodes\x1b[0m
$ sf nodes list --state pending --state running

\x1b[2m# List nodes in JSON format\x1b[0m
$ sf nodes list --json
`,
Expand Down