11import React from "react" ;
2- import { Command } from "@commander-js/extra-typings" ;
2+ import { Command , Option } from "@commander-js/extra-typings" ;
33import { brightBlack , gray } from "jsr:@std/fmt/colors" ;
44import console from "node:console" ;
55import ora from "ora" ;
@@ -20,6 +20,7 @@ import { handleNodesError, nodesClient } from "../../nodesClient.ts";
2020import { Row } from "../Row.tsx" ;
2121import {
2222 createNodesTable ,
23+ DEFAULT_NODE_LS_LIMIT ,
2324 getLastVM ,
2425 getStatusColor ,
2526 getVMStatusColor ,
@@ -32,6 +33,16 @@ dayjs.extend(utc);
3233dayjs . extend ( advanced ) ;
3334dayjs . extend ( timezone ) ;
3435
36+ // Valid node status values for filtering
37+ const VALID_STATES = [
38+ "pending" ,
39+ "awaitingcapacity" ,
40+ "running" ,
41+ "released" ,
42+ "failed" ,
43+ "terminated" ,
44+ ] as const ;
45+
3546// Helper component to display VMs in a table format using Ink
3647function VMTable ( { vms } : { vms : NonNullable < SFCNodes . Node [ "vms" ] > [ "data" ] } ) {
3748 const sortedVms = vms . sort ( ( a , b ) => b . updated_at - a . updated_at ) ;
@@ -447,27 +458,36 @@ async function listNodesAction(options: ReturnType<typeof list.opts>) {
447458
448459 spinner . stop ( ) ;
449460
461+ const filteredNodes = ( options . status ?. length )
462+ ? nodes . filter ( ( n ) =>
463+ options . status ?. length &&
464+ options . status . includes ( n . status )
465+ )
466+ : nodes ;
467+
450468 if ( options . json ) {
451- console . log ( JSON . stringify ( nodes , null , 2 ) ) ;
469+ console . log ( JSON . stringify ( filteredNodes , null , 2 ) ) ;
452470 return ;
453471 }
454472
455- if ( nodes . length === 0 ) {
473+ if ( filteredNodes . length === 0 ) {
456474 console . log ( "No nodes found." ) ;
457475 console . log ( gray ( "\nCreate your first node:" ) ) ;
458476 console . log ( " sf nodes create my-first-node" ) ;
459477 return ;
460478 }
461479
462480 if ( options . verbose ) {
463- render ( < NodesVerboseDisplay nodes = { nodes } /> ) ;
481+ render (
482+ < NodesVerboseDisplay nodes = { filteredNodes . slice ( 0 , options . limit ) } /> ,
483+ ) ;
464484 } else {
465- console . log ( createNodesTable ( nodes ) ) ;
485+ console . log ( createNodesTable ( filteredNodes , options . limit ) ) ;
466486 console . log (
467487 gray (
468- `\nFound ${ nodes . length } ${
469- pluralizeNodes ( nodes . length )
470- } . Use --verbose for detailed information, such as previous virtual machines.`,
488+ `\nFound ${ filteredNodes . length } ${
489+ pluralizeNodes ( filteredNodes . length )
490+ } total . Use --verbose for detailed information, such as previous virtual machines.`,
471491 ) ,
472492 ) ;
473493
@@ -476,7 +496,7 @@ async function listNodesAction(options: ReturnType<typeof list.opts>) {
476496 const seenLabels = new Set < string > ( ) ;
477497
478498 // Sort nodes by created_at (newest first), fallback to index for consistent ordering
479- const sortedNodes = [ ...nodes ] . sort ( ( a , b ) => {
499+ const sortedNodes = [ ...filteredNodes ] . sort ( ( a , b ) => {
480500 const aTime = a . created_at || 0 ;
481501 const bTime = b . created_at || 0 ;
482502 return bTime - aTime ; // Newest first
@@ -513,6 +533,16 @@ const list = new Command("list")
513533 . description ( "List all compute nodes" )
514534 . showHelpAfterError ( )
515535 . option ( "--verbose" , "Show detailed information for each node" )
536+ . option (
537+ "--limit <number>" ,
538+ "Limit the number of nodes to display" ,
539+ Number . parseInt ,
540+ DEFAULT_NODE_LS_LIMIT ,
541+ )
542+ . addOption (
543+ new Option ( "--status <status...>" , "Filter by node status" )
544+ . choices ( VALID_STATES as ( readonly SFCNodes . Status [ ] ) ) ,
545+ )
516546 . addOption ( jsonOption )
517547 . addHelpText (
518548 "after" ,
@@ -524,6 +554,12 @@ Next Steps:\n
524554 \x1b[2m# List all nodes with detailed information\x1b[0m
525555 $ sf nodes list --verbose
526556
557+ \x1b[2m# List up to 100 nodes\x1b[0m
558+ $ sf nodes list --limit 100
559+
560+ \x1b[2m# List pending or running nodes\x1b[0m
561+ $ sf nodes list --status pending running
562+
527563 \x1b[2m# List nodes in JSON format\x1b[0m
528564 $ sf nodes list --json
529565` ,
0 commit comments