@@ -19,6 +19,7 @@ import (
1919 kernel "github.com/onkernel/kernel-go-sdk"
2020 "github.com/onkernel/kernel-go-sdk/option"
2121 "github.com/pterm/pterm"
22+ "github.com/samber/lo"
2223 "github.com/spf13/cobra"
2324)
2425
@@ -64,6 +65,8 @@ func init() {
6465 deployCmd .AddCommand (deployLogsCmd )
6566
6667 deployHistoryCmd .Flags ().Int ("limit" , 20 , "Max deployments to return (default 20)" )
68+ deployHistoryCmd .Flags ().Int ("per-page" , 20 , "Items per page (alias of --limit)" )
69+ deployHistoryCmd .Flags ().Int ("page" , 1 , "Page number (1-based)" )
6770 deployCmd .AddCommand (deployHistoryCmd )
6871
6972 // Flags for GitHub deploy
@@ -354,65 +357,116 @@ func runDeployHistory(cmd *cobra.Command, args []string) error {
354357 client := getKernelClient (cmd )
355358
356359 lim , _ := cmd .Flags ().GetInt ("limit" )
360+ perPage , _ := cmd .Flags ().GetInt ("per-page" )
361+ page , _ := cmd .Flags ().GetInt ("page" )
362+
363+ // Prefer page/per-page when provided; map legacy --limit otherwise
364+ usePager := cmd .Flags ().Changed ("per-page" ) || cmd .Flags ().Changed ("page" )
365+ if ! usePager && cmd .Flags ().Changed ("limit" ) {
366+ if lim < 0 {
367+ lim = 0
368+ }
369+ perPage = lim
370+ page = 1
371+ }
372+ if perPage <= 0 {
373+ perPage = 20
374+ }
375+ if page <= 0 {
376+ page = 1
377+ }
357378
358- var appNames []string
379+ // Build server-side paginated request
380+ var appNameFilter string
359381 if len (args ) == 1 {
360- appNames = []string {args [0 ]}
361- } else {
362- apps , err := client .Apps .List (cmd .Context (), kernel.AppListParams {})
363- if err != nil {
364- pterm .Error .Printf ("Failed to list applications: %v\n " , err )
365- return nil
366- }
367- for _ , a := range * apps {
368- appNames = append (appNames , a .AppName )
369- }
370- // de-duplicate app names
371- seenApps := map [string ]struct {}{}
372- uniq := make ([]string , 0 , len (appNames ))
373- for _ , n := range appNames {
374- if _ , ok := seenApps [n ]; ok {
375- continue
376- }
377- seenApps [n ] = struct {}{}
378- uniq = append (uniq , n )
379- }
380- appNames = uniq
382+ appNameFilter = strings .TrimSpace (args [0 ])
381383 }
382384
383- rows := 0
384- table := pterm.TableData {{"Deployment ID" , "Created At" , "Region" , "Status" , "Entrypoint" , "Reason" }}
385- AppsLoop:
386- for _ , appName := range appNames {
387- params := kernel.DeploymentListParams {AppName : kernel .Opt (appName )}
388- pterm .Debug .Printf ("Listing deployments for app '%s'...\n " , appName )
389- deployments , err := client .Deployments .List (cmd .Context (), params )
390- if err != nil {
391- pterm .Error .Printf ("Failed to list deployments for '%s': %v\n " , appName , err )
392- continue
393- }
394- for _ , dep := range deployments .Items {
395- created := util .FormatLocal (dep .CreatedAt )
396- status := string (dep .Status )
397- table = append (table , []string {
398- dep .ID ,
399- created ,
400- string (dep .Region ),
401- status ,
402- dep .EntrypointRelPath ,
403- dep .StatusReason ,
404- })
405- rows ++
406- if lim > 0 && rows >= lim {
407- break AppsLoop
408- }
409- }
385+ params := kernel.DeploymentListParams {}
386+ if appNameFilter != "" {
387+ params .AppName = kernel .Opt (appNameFilter )
388+ }
389+ // Request one extra item to detect hasMore
390+ params .Limit = kernel .Opt (int64 (perPage + 1 ))
391+ params .Offset = kernel .Opt (int64 ((page - 1 ) * perPage ))
392+
393+ pterm .Debug .Println ("Fetching deployments..." )
394+ deployments , err := client .Deployments .List (cmd .Context (), params )
395+ if err != nil {
396+ pterm .Error .Printf ("Failed to list deployments: %v\n " , err )
397+ return nil
410398 }
411- if len (table ) == 1 {
399+ if deployments == nil || len (deployments . Items ) == 0 {
412400 pterm .Info .Println ("No deployments found" )
413401 return nil
414402 }
403+
404+ items := deployments .Items
405+ hasMore := false
406+ if len (items ) > perPage {
407+ hasMore = true
408+ items = items [:perPage ]
409+ }
410+ itemsThisPage := len (items )
411+
412+ table := pterm.TableData {{"Deployment ID" , "Created At" , "Region" , "Status" , "Entrypoint" , "Reason" }}
413+ for _ , dep := range items {
414+ created := util .FormatLocal (dep .CreatedAt )
415+ status := string (dep .Status )
416+ table = append (table , []string {
417+ dep .ID ,
418+ created ,
419+ string (dep .Region ),
420+ status ,
421+ dep .EntrypointRelPath ,
422+ dep .StatusReason ,
423+ })
424+ }
415425 pterm .DefaultTable .WithHasHeader ().WithData (table ).Render ()
426+
427+ fmt .Printf ("\n Page: %d Per-page: %d Items this page: %d Has more: %s\n " , page , perPage , itemsThisPage , lo .Ternary (hasMore , "yes" , "no" ))
428+ if hasMore {
429+ nextPage := page + 1
430+ nextCmd := fmt .Sprintf ("kernel deploy history --page %d --per-page %d" , nextPage , perPage )
431+ if appNameFilter != "" {
432+ nextCmd = fmt .Sprintf ("kernel deploy history %s --page %d --per-page %d" , appNameFilter , nextPage , perPage )
433+ }
434+ fmt .Printf ("Next: %s\n " , nextCmd )
435+ }
436+ // Concise notes when user-specified per-page/limit/page are outside API-allowed range
437+ if cmd .Flags ().Changed ("per-page" ) {
438+ if v , _ := cmd .Flags ().GetInt ("per-page" ); v > 100 {
439+ pterm .Warning .Printfln ("Requested --per-page %d; capped to 100." , v )
440+ } else if v < 1 {
441+ if cmd .Flags ().Changed ("page" ) {
442+ if p , _ := cmd .Flags ().GetInt ("page" ); p < 1 {
443+ pterm .Warning .Println ("Requested --per-page <1 and --page <1; using per-page=20, page=1." )
444+ } else {
445+ pterm .Warning .Println ("Requested --per-page <1; using per-page=20." )
446+ }
447+ } else {
448+ pterm .Warning .Println ("Requested --per-page <1; using per-page=20." )
449+ }
450+ }
451+ } else if ! usePager && cmd .Flags ().Changed ("limit" ) {
452+ if lim > 100 {
453+ pterm .Warning .Printfln ("Requested --limit %d; capped to 100." , lim )
454+ } else if lim < 1 {
455+ if cmd .Flags ().Changed ("page" ) {
456+ if p , _ := cmd .Flags ().GetInt ("page" ); p < 1 {
457+ pterm .Warning .Println ("Requested --limit <1 and --page <1; using per-page=20, page=1." )
458+ } else {
459+ pterm .Warning .Println ("Requested --limit <1; using per-page=20." )
460+ }
461+ } else {
462+ pterm .Warning .Println ("Requested --limit <1; using per-page=20." )
463+ }
464+ }
465+ } else if cmd .Flags ().Changed ("page" ) {
466+ if p , _ := cmd .Flags ().GetInt ("page" ); p < 1 {
467+ pterm .Warning .Println ("Requested --page <1; using page=1." )
468+ }
469+ }
416470 return nil
417471}
418472
0 commit comments