package cmd import ( "fmt" "os" "github.com/kb-search/kb/internal/api" "github.com/kb-search/kb/internal/output" "github.com/spf13/cobra" ) var jobsCmd = &cobra.Command{ Use: "jobs [id]", Short: "List jobs or show job details", Args: cobra.MaximumNArgs(1), RunE: runJobs, } func init() { jobsCmd.Flags().String("status", "", "filter by status") rootCmd.AddCommand(jobsCmd) } func runJobs(cmd *cobra.Command, args []string) error { client := api.NewClient() if len(args) == 1 { // Show single job resp, err := client.Get("/api/v1/jobs/" + args[0]) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if err := api.CheckError(resp); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if output.IsJSON() { var raw interface{} if err := api.DecodeJSON(resp, &raw); err != nil { return fmt.Errorf("failed to decode response: %w", err) } output.PrintJSON(raw) return nil } var job struct { ID int `json:"id"` Status string `json:"status"` Filename string `json:"filename"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` Error string `json:"error"` } if err := api.DecodeJSON(resp, &job); err != nil { return fmt.Errorf("failed to decode response: %w", err) } pairs := [][]string{ {"ID", fmt.Sprintf("%d", job.ID)}, {"Status", job.Status}, {"Filename", job.Filename}, {"Created", job.CreatedAt}, {"Updated", job.UpdatedAt}, } if job.Error != "" { pairs = append(pairs, []string{"Error", job.Error}) } output.PrintKeyValue(pairs) return nil } // List jobs path := "/api/v1/jobs" status, _ := cmd.Flags().GetString("status") if status != "" { path += "?status=" + status } resp, err := client.Get(path) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if err := api.CheckError(resp); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if output.IsJSON() { var raw interface{} if err := api.DecodeJSON(resp, &raw); err != nil { return fmt.Errorf("failed to decode response: %w", err) } output.PrintJSON(raw) return nil } var jobs []struct { ID int `json:"id"` Status string `json:"status"` Filename string `json:"filename"` } if err := api.DecodeJSON(resp, &jobs); err != nil { return fmt.Errorf("failed to decode response: %w", err) } if len(jobs) == 0 { fmt.Println("No jobs found.") return nil } headers := []string{"ID", "STATUS", "FILENAME"} var rows [][]string for _, j := range jobs { rows = append(rows, []string{fmt.Sprintf("%d", j.ID), j.Status, j.Filename}) } output.PrintTable(headers, rows) return nil }