refactor(cli): overhaul help output to match gh CLI style
- Add gh-style grouped help with CORE/RUNTIME/ADDITIONAL COMMANDS sections - Use UPPERCASE section headers (USAGE, FLAGS, EXAMPLES, LEARN MORE) - Format commands as "name: description" with automatic alignment - Add ENVIRONMENT VARIABLES and EXAMPLES sections to root help - Apply consistent templates to root, subcommand, and leaf commands - Update descriptions from "Manage X" to "Work with X" for gh parity Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0771c15a59
commit
4afef09a03
12 changed files with 184 additions and 21 deletions
|
|
@ -17,7 +17,7 @@ import (
|
|||
|
||||
var agentCmd = &cobra.Command{
|
||||
Use: "agent",
|
||||
Short: "Manage agents",
|
||||
Short: "Work with agents",
|
||||
}
|
||||
|
||||
var agentListCmd = &cobra.Command{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
var attachmentCmd = &cobra.Command{
|
||||
Use: "attachment",
|
||||
Short: "Manage attachments",
|
||||
Short: "Work with attachments",
|
||||
}
|
||||
|
||||
var attachmentDownloadCmd = &cobra.Command{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
var authCmd = &cobra.Command{
|
||||
Use: "auth",
|
||||
Short: "Manage authentication",
|
||||
Short: "Authenticate multica with Multica",
|
||||
}
|
||||
|
||||
var authLoginCmd = &cobra.Command{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
var configCmd = &cobra.Command{
|
||||
Use: "config",
|
||||
Short: "Show CLI configuration",
|
||||
Short: "Manage configuration for multica",
|
||||
RunE: runConfigShow,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import (
|
|||
|
||||
var daemonCmd = &cobra.Command{
|
||||
Use: "daemon",
|
||||
Short: "Manage the local agent runtime daemon",
|
||||
Short: "Control the local agent runtime daemon",
|
||||
}
|
||||
|
||||
var daemonStartCmd = &cobra.Command{
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
var issueCmd = &cobra.Command{
|
||||
Use: "issue",
|
||||
Short: "Manage issues",
|
||||
Short: "Work with issues",
|
||||
}
|
||||
|
||||
var issueListCmd = &cobra.Command{
|
||||
|
|
@ -63,7 +63,7 @@ var issueStatusCmd = &cobra.Command{
|
|||
|
||||
var issueCommentCmd = &cobra.Command{
|
||||
Use: "comment",
|
||||
Short: "Manage issue comments",
|
||||
Short: "Work with issue comments",
|
||||
}
|
||||
|
||||
var issueCommentListCmd = &cobra.Command{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
var repoCmd = &cobra.Command{
|
||||
Use: "repo",
|
||||
Short: "Manage repositories",
|
||||
Short: "Work with repositories",
|
||||
}
|
||||
|
||||
var repoCheckoutCmd = &cobra.Command{
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
var runtimeCmd = &cobra.Command{
|
||||
Use: "runtime",
|
||||
Short: "Manage agent runtimes",
|
||||
Short: "Work with agent runtimes",
|
||||
}
|
||||
|
||||
var runtimeListCmd = &cobra.Command{
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
var skillCmd = &cobra.Command{
|
||||
Use: "skill",
|
||||
Short: "Manage skills",
|
||||
Short: "Work with skills",
|
||||
}
|
||||
|
||||
var skillListCmd = &cobra.Command{
|
||||
|
|
@ -62,7 +62,7 @@ var skillImportCmd = &cobra.Command{
|
|||
|
||||
var skillFilesCmd = &cobra.Command{
|
||||
Use: "files",
|
||||
Short: "Manage skill files",
|
||||
Short: "Work with skill files",
|
||||
}
|
||||
|
||||
var skillFilesListCmd = &cobra.Command{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
var workspaceCmd = &cobra.Command{
|
||||
Use: "workspace",
|
||||
Short: "Manage workspaces",
|
||||
Short: "Work with workspaces",
|
||||
}
|
||||
|
||||
var workspaceListCmd = &cobra.Command{
|
||||
|
|
|
|||
142
server/cmd/multica/help.go
Normal file
142
server/cmd/multica/help.go
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// Command group IDs used across the CLI.
|
||||
const (
|
||||
groupCore = "core"
|
||||
groupRuntime = "runtime"
|
||||
groupAdditional = "additional"
|
||||
)
|
||||
|
||||
// initHelp configures the root command to use gh-style help output.
|
||||
func initHelp(root *cobra.Command) {
|
||||
root.SetHelpTemplate(rootHelpTemplate)
|
||||
root.SetUsageTemplate(rootHelpTemplate)
|
||||
root.CompletionOptions.HiddenDefaultCmd = true
|
||||
|
||||
root.AddGroup(
|
||||
&cobra.Group{ID: groupCore, Title: "CORE COMMANDS"},
|
||||
&cobra.Group{ID: groupRuntime, Title: "RUNTIME COMMANDS"},
|
||||
&cobra.Group{ID: groupAdditional, Title: "ADDITIONAL COMMANDS"},
|
||||
)
|
||||
|
||||
// Apply gh-style templates to all commands recursively.
|
||||
applyTemplates(root)
|
||||
}
|
||||
|
||||
func applyTemplates(cmd *cobra.Command) {
|
||||
for _, c := range cmd.Commands() {
|
||||
if c.HasSubCommands() {
|
||||
c.SetHelpTemplate(subHelpTemplate)
|
||||
c.SetUsageTemplate(subHelpTemplate)
|
||||
} else {
|
||||
c.SetHelpTemplate(leafHelpTemplate)
|
||||
c.SetUsageTemplate(leafHelpTemplate)
|
||||
}
|
||||
applyTemplates(c)
|
||||
}
|
||||
}
|
||||
|
||||
// formatCommandList formats a list of commands in "name: description" style
|
||||
// with automatic alignment, matching gh's output.
|
||||
func formatCommandList(cmds []*cobra.Command) string {
|
||||
if len(cmds) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
maxLen := 0
|
||||
for _, c := range cmds {
|
||||
if c.IsAvailableCommand() && len(c.Name()) > maxLen {
|
||||
maxLen = len(c.Name())
|
||||
}
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
for _, c := range cmds {
|
||||
if !c.IsAvailableCommand() {
|
||||
continue
|
||||
}
|
||||
padding := strings.Repeat(" ", maxLen-len(c.Name()))
|
||||
fmt.Fprintf(&b, " %s:%s %s\n", c.Name(), padding, c.Short)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// commandsInGroup returns commands that belong to a specific group.
|
||||
func commandsInGroup(cmds []*cobra.Command, groupID string) []*cobra.Command {
|
||||
var result []*cobra.Command
|
||||
for _, c := range cmds {
|
||||
if c.GroupID == groupID && c.IsAvailableCommand() {
|
||||
result = append(result, c)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func init() {
|
||||
cobra.AddTemplateFuncs(template.FuncMap{
|
||||
"formatCommandList": formatCommandList,
|
||||
"commandsInGroup": commandsInGroup,
|
||||
})
|
||||
}
|
||||
|
||||
var rootHelpTemplate = `Work seamlessly with Multica from the command line.
|
||||
|
||||
USAGE
|
||||
multica <command> <subcommand> [flags]
|
||||
{{range .Groups}}
|
||||
{{.Title}}
|
||||
{{formatCommandList (commandsInGroup $.Commands .ID)}}
|
||||
{{- end}}
|
||||
FLAGS
|
||||
{{.LocalFlags.FlagUsages}}
|
||||
EXAMPLES
|
||||
$ multica login
|
||||
$ multica issue list --output json
|
||||
$ multica daemon start
|
||||
$ multica agent list --output json
|
||||
|
||||
ENVIRONMENT VARIABLES
|
||||
MULTICA_SERVER_URL Override the default server URL
|
||||
MULTICA_WORKSPACE_ID Set the active workspace
|
||||
|
||||
LEARN MORE
|
||||
Use ` + "`multica <command> <subcommand> --help`" + ` for more information about a command.
|
||||
`
|
||||
|
||||
var subHelpTemplate = `{{.Short}}
|
||||
|
||||
USAGE
|
||||
{{.CommandPath}} <command> [flags]
|
||||
|
||||
COMMANDS
|
||||
{{formatCommandList .Commands}}
|
||||
INHERITED FLAGS
|
||||
--help Show help for command
|
||||
|
||||
LEARN MORE
|
||||
Use ` + "`{{.CommandPath}} <command> --help`" + ` for more information about a command.
|
||||
`
|
||||
|
||||
var leafHelpTemplate = `{{if .Long}}{{.Long}}{{else}}{{.Short}}{{end}}
|
||||
|
||||
USAGE
|
||||
{{.UseLine}}
|
||||
{{- if .HasLocalFlags}}
|
||||
|
||||
FLAGS
|
||||
{{.LocalFlags.FlagUsages}}
|
||||
{{- end}}
|
||||
INHERITED FLAGS
|
||||
--help Show help for command
|
||||
|
||||
LEARN MORE
|
||||
Use ` + "`multica <command> <subcommand> --help`" + ` for more information about a command.
|
||||
`
|
||||
|
|
@ -15,7 +15,7 @@ var (
|
|||
var rootCmd = &cobra.Command{
|
||||
Use: "multica",
|
||||
Short: "Multica CLI — local agent runtime and management tool",
|
||||
Long: "multica manages local agent runtimes and provides control commands for the Multica platform.",
|
||||
Long: "Work seamlessly with Multica from the command line.",
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
}
|
||||
|
|
@ -25,19 +25,40 @@ func init() {
|
|||
rootCmd.PersistentFlags().String("workspace-id", "", "Workspace ID (env: MULTICA_WORKSPACE_ID)")
|
||||
rootCmd.PersistentFlags().String("profile", "", "Configuration profile name (e.g. dev) — isolates config, daemon state, and workspaces")
|
||||
|
||||
rootCmd.AddCommand(loginCmd)
|
||||
rootCmd.AddCommand(authCmd)
|
||||
rootCmd.AddCommand(daemonCmd)
|
||||
// Core commands
|
||||
issueCmd.GroupID = groupCore
|
||||
agentCmd.GroupID = groupCore
|
||||
workspaceCmd.GroupID = groupCore
|
||||
repoCmd.GroupID = groupCore
|
||||
skillCmd.GroupID = groupCore
|
||||
|
||||
// Runtime commands
|
||||
daemonCmd.GroupID = groupRuntime
|
||||
runtimeCmd.GroupID = groupRuntime
|
||||
|
||||
// Additional commands
|
||||
authCmd.GroupID = groupAdditional
|
||||
loginCmd.GroupID = groupAdditional
|
||||
attachmentCmd.GroupID = groupAdditional
|
||||
configCmd.GroupID = groupAdditional
|
||||
updateCmd.GroupID = groupAdditional
|
||||
versionCmd.GroupID = groupAdditional
|
||||
|
||||
rootCmd.AddCommand(issueCmd)
|
||||
rootCmd.AddCommand(agentCmd)
|
||||
rootCmd.AddCommand(workspaceCmd)
|
||||
rootCmd.AddCommand(configCmd)
|
||||
rootCmd.AddCommand(issueCmd)
|
||||
rootCmd.AddCommand(attachmentCmd)
|
||||
rootCmd.AddCommand(repoCmd)
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
rootCmd.AddCommand(updateCmd)
|
||||
rootCmd.AddCommand(skillCmd)
|
||||
rootCmd.AddCommand(daemonCmd)
|
||||
rootCmd.AddCommand(runtimeCmd)
|
||||
rootCmd.AddCommand(authCmd)
|
||||
rootCmd.AddCommand(loginCmd)
|
||||
rootCmd.AddCommand(attachmentCmd)
|
||||
rootCmd.AddCommand(configCmd)
|
||||
rootCmd.AddCommand(updateCmd)
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
|
||||
initHelp(rootCmd)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue