@@ -83,6 +83,36 @@ type Command struct {
8383 Subcommands map [string ]* Command
8484}
8585
86+ // CommandSchema is a JSON-serializable representation of a command for LLM parsing
87+ type CommandSchema struct {
88+ Name string `json:"name"`
89+ Description string `json:"description"`
90+ Usage string `json:"usage,omitempty"`
91+ Subcommands map [string ]* CommandSchema `json:"subcommands,omitempty"`
92+ }
93+
94+ // toSchema converts a Command to its JSON-serializable schema
95+ func (cmd * Command ) toSchema () * CommandSchema {
96+ schema := & CommandSchema {
97+ Name : cmd .Name ,
98+ Description : cmd .Description ,
99+ Usage : cmd .Usage ,
100+ }
101+
102+ if len (cmd .Subcommands ) > 0 {
103+ schema .Subcommands = make (map [string ]* CommandSchema )
104+ for name , subcmd := range cmd .Subcommands {
105+ // Skip internal commands (prefixed with _)
106+ if strings .HasPrefix (name , "_" ) {
107+ continue
108+ }
109+ schema .Subcommands [name ] = subcmd .toSchema ()
110+ }
111+ }
112+
113+ return schema
114+ }
115+
86116// CLI manages the command-line interface
87117type CLI struct {
88118 rootCmd * Command
@@ -206,14 +236,26 @@ func sanitizeTmuxSessionName(repoName string) string {
206236// Execute executes the CLI with the given arguments
207237func (c * CLI ) Execute (args []string ) error {
208238 if len (args ) == 0 {
209- return c .showHelp ()
239+ return c .showHelp (false )
210240 }
211241
212242 // Check for --version or -v flag at top level
213243 if args [0 ] == "--version" || args [0 ] == "-v" {
214244 return c .showVersion ()
215245 }
216246
247+ // Check for --help or -h with optional --json at top level
248+ if args [0 ] == "--help" || args [0 ] == "-h" {
249+ flags , _ := ParseFlags (args )
250+ outputJSON := flags ["json" ] == "true"
251+ return c .showHelp (outputJSON )
252+ }
253+
254+ // Check for --json alone (output full command tree)
255+ if args [0 ] == "--json" {
256+ return c .showHelp (true )
257+ }
258+
217259 return c .executeCommand (c .rootCmd , args )
218260}
219261
@@ -251,12 +293,19 @@ func (c *CLI) executeCommand(cmd *Command, args []string) error {
251293 if cmd .Run != nil {
252294 return cmd .Run ([]string {})
253295 }
254- return c .showCommandHelp (cmd )
296+ return c .showCommandHelp (cmd , false )
255297 }
256298
257- // Check for --help or -h flag
299+ // Check for --help or -h flag with optional --json
258300 if args [0 ] == "--help" || args [0 ] == "-h" {
259- return c .showCommandHelp (cmd )
301+ flags , _ := ParseFlags (args )
302+ outputJSON := flags ["json" ] == "true"
303+ return c .showCommandHelp (cmd , outputJSON )
304+ }
305+
306+ // Check for --json alone (output command schema)
307+ if args [0 ] == "--json" {
308+ return c .showCommandHelp (cmd , true )
260309 }
261310
262311 // Check for subcommands
@@ -273,7 +322,14 @@ func (c *CLI) executeCommand(cmd *Command, args []string) error {
273322}
274323
275324// showHelp shows the main help message
276- func (c * CLI ) showHelp () error {
325+ func (c * CLI ) showHelp (outputJSON bool ) error {
326+ if outputJSON {
327+ schema := c .rootCmd .toSchema ()
328+ encoder := json .NewEncoder (os .Stdout )
329+ encoder .SetIndent ("" , " " )
330+ return encoder .Encode (schema )
331+ }
332+
277333 fmt .Println ("multiclaude - repo-centric orchestrator for Claude Code" )
278334 fmt .Println ()
279335 fmt .Println ("Usage: multiclaude <command> [options]" )
@@ -286,11 +342,19 @@ func (c *CLI) showHelp() error {
286342
287343 fmt .Println ()
288344 fmt .Println ("Use 'multiclaude <command> --help' for more information about a command." )
345+ fmt .Println ("Use 'multiclaude --json' for machine-readable command tree (LLM-friendly)." )
289346 return nil
290347}
291348
292349// showCommandHelp shows help for a specific command
293- func (c * CLI ) showCommandHelp (cmd * Command ) error {
350+ func (c * CLI ) showCommandHelp (cmd * Command , outputJSON bool ) error {
351+ if outputJSON {
352+ schema := cmd .toSchema ()
353+ encoder := json .NewEncoder (os .Stdout )
354+ encoder .SetIndent ("" , " " )
355+ return encoder .Encode (schema )
356+ }
357+
294358 fmt .Printf ("%s - %s\n " , cmd .Name , cmd .Description )
295359 fmt .Println ()
296360 if cmd .Usage != "" {
0 commit comments