11package cmd
22
33import (
4+ "encoding/json"
45 "fmt"
56 "os"
67 "os/exec"
1718 listInstalled bool
1819 listOutdated bool
1920 listCurrent bool
21+ listJSON bool
2022)
2123
2224// agentsCmd represents the agents command
@@ -83,10 +85,25 @@ func init() {
8385 agentsListCmd .Flags ().BoolVar (& listInstalled , "installed" , false , "List only installed agents" )
8486 agentsListCmd .Flags ().BoolVar (& listOutdated , "outdated" , false , "List outdated agents with version comparison table" )
8587 agentsListCmd .Flags ().BoolVar (& listCurrent , "current" , false , "Check and display latest versions from the web" )
88+ agentsListCmd .Flags ().BoolVar (& listJSON , "json" , false , "Output in JSON format" )
8689 agentsInstallCmd .Flags ().BoolVar (& installAll , "all" , false , "Install all agents" )
8790 agentsUpgradeCmd .Flags ().BoolVar (& installAll , "all" , false , "Upgrade all agents" )
8891}
8992
93+ // AgentListJSON represents an agent in JSON output
94+ type AgentListJSON struct {
95+ Name string `json:"name"`
96+ Command string `json:"command"`
97+ Description string `json:"description"`
98+ Docs string `json:"docs"`
99+ Installed bool `json:"installed"`
100+ Path string `json:"path,omitempty"`
101+ Version string `json:"version,omitempty"`
102+ LatestVersion string `json:"latest_version,omitempty"`
103+ HasUpdate bool `json:"has_update,omitempty"`
104+ InstallCmd string `json:"install_cmd,omitempty"`
105+ }
106+
90107func runAgentsList (cmd * cobra.Command , args []string ) {
91108 agents := registry .GetAll ()
92109
@@ -117,6 +134,12 @@ func runAgentsList(cmd *cobra.Command, args []string) {
117134 filteredAgents = append (filteredAgents , agent )
118135 }
119136
137+ // Handle JSON output
138+ if listJSON {
139+ outputAgentsJSON (filteredAgents , showVersionInfo )
140+ return
141+ }
142+
120143 // Determine title based on flags
121144 title := "AI Agent CLIs"
122145 if listInstalled {
@@ -207,21 +230,18 @@ func runAgentsList(cmd *cobra.Command, args []string) {
207230 fmt .Println ()
208231}
209232
233+ // agentVersionRow represents version information for an agent
234+ type agentVersionRow struct {
235+ name string
236+ installed bool
237+ current string
238+ latest string
239+ hasUpdate bool
240+ canCheck bool
241+ }
242+
210243// showOutdatedTable displays a table of agents with version comparison
211244func showOutdatedTable (agents []* registry.AgentDefinition ) {
212- fmt .Println ("\n 📊 Agent Version Status" )
213- fmt .Println (strings .Repeat ("=" , 85 ))
214- fmt .Println ()
215-
216- // Build table data
217- type row struct {
218- name string
219- installed bool
220- current string
221- latest string
222- hasUpdate bool
223- canCheck bool
224- }
225245
226246 // Fetch version info in parallel
227247 type versionResult struct {
@@ -232,7 +252,7 @@ func showOutdatedTable(agents []*registry.AgentDefinition) {
232252 }
233253
234254 resultChan := make (chan versionResult , len (agents ))
235- rows := make ([]row , len (agents ))
255+ rows := make ([]agentVersionRow , len (agents ))
236256 outdatedCount := 0
237257
238258 // Launch parallel version checks
@@ -273,7 +293,7 @@ func showOutdatedTable(agents []*registry.AgentDefinition) {
273293 agent := agents [result .index ]
274294 installed := result .current != "not installed"
275295
276- r := row {
296+ r := agentVersionRow {
277297 name : agent .Name ,
278298 installed : installed ,
279299 current : result .current ,
@@ -299,6 +319,17 @@ func showOutdatedTable(agents []*registry.AgentDefinition) {
299319 }
300320 close (resultChan )
301321
322+ // Output JSON format if requested
323+ if listJSON {
324+ outputOutdatedJSON (rows )
325+ return
326+ }
327+
328+ // Human-readable format
329+ fmt .Println ("\n 📊 Agent Version Status" )
330+ fmt .Println (strings .Repeat ("=" , 85 ))
331+ fmt .Println ()
332+
302333 // Print table header
303334 fmt .Printf ("%-12s %-24s %-24s %s\n " ,
304335 "Agent" , "Installed Version" , "Latest Version" , "Update" )
@@ -523,6 +554,106 @@ func runAgentsUpgrade(cmd *cobra.Command, args []string) {
523554 }
524555}
525556
557+ // outputAgentsJSON outputs agent list in JSON format
558+ func outputAgentsJSON (agents []* registry.AgentDefinition , showVersionInfo bool ) {
559+ var jsonAgents []AgentListJSON
560+
561+ for _ , agent := range agents {
562+ installed := isAgentInstalled (agent .Command )
563+
564+ agentJSON := AgentListJSON {
565+ Name : agent .Name ,
566+ Command : agent .Command ,
567+ Description : agent .Description ,
568+ Docs : agent .Docs ,
569+ Installed : installed ,
570+ }
571+
572+ if installed {
573+ if path , err := exec .LookPath (agent .Command ); err == nil {
574+ agentJSON .Path = path
575+ }
576+
577+ version := registry .GetInstalledVersion (agent .Command )
578+ if version != "" {
579+ agentJSON .Version = version
580+ }
581+
582+ // Check for updates if showVersionInfo is true
583+ if showVersionInfo && agent .PackageManager != "" {
584+ latest , err := agent .GetLatestVersion ()
585+ if err == nil {
586+ agentJSON .LatestVersion = latest
587+ if version != "" {
588+ cmp , _ := registry .CompareVersions (version , latest )
589+ agentJSON .HasUpdate = cmp < 0
590+ }
591+ }
592+ }
593+ } else {
594+ // Get install command for non-installed agents
595+ installCmd , err := agent .GetInstallCommand ()
596+ if err == nil {
597+ if agent .IsInstallable () {
598+ agentJSON .InstallCmd = fmt .Sprintf ("agentpipe agents install %s" , strings .ToLower (agent .Name ))
599+ } else {
600+ agentJSON .InstallCmd = installCmd
601+ }
602+ }
603+
604+ // Show latest version if showVersionInfo is set
605+ if showVersionInfo && agent .PackageManager != "" {
606+ latest , err := agent .GetLatestVersion ()
607+ if err == nil {
608+ agentJSON .LatestVersion = latest
609+ }
610+ }
611+ }
612+
613+ jsonAgents = append (jsonAgents , agentJSON )
614+ }
615+
616+ output , err := json .MarshalIndent (jsonAgents , "" , " " )
617+ if err != nil {
618+ fmt .Fprintf (os .Stderr , "Error generating JSON output: %v\n " , err )
619+ os .Exit (1 )
620+ }
621+
622+ fmt .Println (string (output ))
623+ }
624+
625+ // outputOutdatedJSON outputs agent version information in JSON format
626+ func outputOutdatedJSON (rows []agentVersionRow ) {
627+ type OutdatedAgentJSON struct {
628+ Name string `json:"name"`
629+ Installed bool `json:"installed"`
630+ CurrentVer string `json:"current_version"`
631+ LatestVer string `json:"latest_version"`
632+ HasUpdate bool `json:"has_update"`
633+ CanCheckVer bool `json:"can_check_version"`
634+ }
635+
636+ var jsonAgents []OutdatedAgentJSON
637+ for _ , r := range rows {
638+ jsonAgents = append (jsonAgents , OutdatedAgentJSON {
639+ Name : r .name ,
640+ Installed : r .installed ,
641+ CurrentVer : r .current ,
642+ LatestVer : r .latest ,
643+ HasUpdate : r .hasUpdate ,
644+ CanCheckVer : r .canCheck ,
645+ })
646+ }
647+
648+ output , err := json .MarshalIndent (jsonAgents , "" , " " )
649+ if err != nil {
650+ fmt .Fprintf (os .Stderr , "Error generating JSON output: %v\n " , err )
651+ os .Exit (1 )
652+ }
653+
654+ fmt .Println (string (output ))
655+ }
656+
526657// isAgentInstalled checks if an agent CLI is available in PATH
527658func isAgentInstalled (command string ) bool {
528659 _ , err := exec .LookPath (command )
0 commit comments