diff --git a/cmd/gh-aw/command_groups_test.go b/cmd/gh-aw/command_groups_test.go index 10e3e5dd7b3..be2a86dadd2 100644 --- a/cmd/gh-aw/command_groups_test.go +++ b/cmd/gh-aw/command_groups_test.go @@ -20,14 +20,18 @@ func TestCommandGroupAssignments(t *testing.T) { {name: "init command in setup group", commandName: "init", expectedGroup: "setup", shouldHaveGroup: true}, {name: "new command in setup group", commandName: "new", expectedGroup: "setup", shouldHaveGroup: true}, {name: "add command in setup group", commandName: "add", expectedGroup: "setup", shouldHaveGroup: true}, + {name: "add-wizard command in setup group", commandName: "add-wizard", expectedGroup: "setup", shouldHaveGroup: true}, {name: "remove command in setup group", commandName: "remove", expectedGroup: "setup", shouldHaveGroup: true}, {name: "update command in setup group", commandName: "update", expectedGroup: "setup", shouldHaveGroup: true}, + {name: "upgrade command in setup group", commandName: "upgrade", expectedGroup: "setup", shouldHaveGroup: true}, {name: "secrets command in setup group", commandName: "secrets", expectedGroup: "setup", shouldHaveGroup: true}, // Development Commands {name: "compile command in development group", commandName: "compile", expectedGroup: "development", shouldHaveGroup: true}, + {name: "validate command in development group", commandName: "validate", expectedGroup: "development", shouldHaveGroup: true}, {name: "mcp command in development group", commandName: "mcp", expectedGroup: "development", shouldHaveGroup: true}, {name: "fix command in development group", commandName: "fix", expectedGroup: "development", shouldHaveGroup: true}, + {name: "domains command in development group", commandName: "domains", expectedGroup: "development", shouldHaveGroup: true}, // Execution Commands {name: "run command in execution group", commandName: "run", expectedGroup: "execution", shouldHaveGroup: true}, @@ -40,10 +44,15 @@ func TestCommandGroupAssignments(t *testing.T) { {name: "audit command in analysis group", commandName: "audit", expectedGroup: "analysis", shouldHaveGroup: true}, {name: "status command in analysis group", commandName: "status", expectedGroup: "analysis", shouldHaveGroup: true}, {name: "list command in analysis group", commandName: "list", expectedGroup: "analysis", shouldHaveGroup: true}, + {name: "health command in analysis group", commandName: "health", expectedGroup: "analysis", shouldHaveGroup: true}, + {name: "checks command in analysis group", commandName: "checks", expectedGroup: "analysis", shouldHaveGroup: true}, // Utilities {name: "mcp-server command in utilities group", commandName: "mcp-server", expectedGroup: "utilities", shouldHaveGroup: true}, {name: "pr command in utilities group", commandName: "pr", expectedGroup: "utilities", shouldHaveGroup: true}, + {name: "completion command in utilities group", commandName: "completion", expectedGroup: "utilities", shouldHaveGroup: true}, + {name: "hash-frontmatter command in utilities group", commandName: "hash-frontmatter", expectedGroup: "utilities", shouldHaveGroup: true}, + {name: "project command in utilities group", commandName: "project", expectedGroup: "utilities", shouldHaveGroup: true}, // Commands without groups (intentionally) {name: "version command without group", commandName: "version", expectedGroup: "", shouldHaveGroup: false}, diff --git a/cmd/gh-aw/main.go b/cmd/gh-aw/main.go index b348ec1607e..7263a1a7c22 100644 --- a/cmd/gh-aw/main.go +++ b/cmd/gh-aw/main.go @@ -529,11 +529,20 @@ func init() { } if cmd.HasAvailableSubCommands() { cmds := cmd.Commands() + // Compute column width dynamically so long command names (e.g. hash-frontmatter) + // are aligned properly instead of overflowing a hard-coded width. + colWidth := 0 + for _, sub := range cmds { + if (sub.IsAvailableCommand() || sub.Name() == "help") && len(sub.Name()) > colWidth { + colWidth = len(sub.Name()) + } + } + colFmt := fmt.Sprintf("\n %%-%ds %%s", colWidth) if len(cmd.Groups()) == 0 { fmt.Fprint(out, "\n\nAvailable Commands:") for _, sub := range cmds { if sub.IsAvailableCommand() || sub.Name() == "help" { - fmt.Fprintf(out, "\n %-11s %s", sub.Name(), sub.Short) + fmt.Fprintf(out, colFmt, sub.Name(), sub.Short) } } } else { @@ -541,7 +550,7 @@ func init() { fmt.Fprintf(out, "\n\n%s", group.Title) for _, sub := range cmds { if sub.GroupID == group.ID && (sub.IsAvailableCommand() || sub.Name() == "help") { - fmt.Fprintf(out, "\n %-11s %s", sub.Name(), sub.Short) + fmt.Fprintf(out, colFmt, sub.Name(), sub.Short) } } } @@ -549,7 +558,7 @@ func init() { fmt.Fprint(out, "\n\nAdditional Commands:") for _, sub := range cmds { if sub.GroupID == "" && (sub.IsAvailableCommand() || sub.Name() == "help") { - fmt.Fprintf(out, "\n %-11s %s", sub.Name(), sub.Short) + fmt.Fprintf(out, colFmt, sub.Name(), sub.Short) } } } diff --git a/pkg/cli/logs_command.go b/pkg/cli/logs_command.go index cc583998b3e..9117b308047 100644 --- a/pkg/cli/logs_command.go +++ b/pkg/cli/logs_command.go @@ -196,7 +196,7 @@ Examples: logsCmd.Flags().Bool("filtered-integrity", false, "Filter to runs with DIFC (data integrity flow control) integrity-filtered items in the gateway logs") logsCmd.Flags().Bool("parse", false, "Run JavaScript parsers on agent logs and firewall logs, writing Markdown to log.md and firewall.md") addJSONFlag(logsCmd) - logsCmd.Flags().Int("timeout", 0, "Download timeout in seconds (0 = no timeout; note: trial uses minutes for its timeout)") + logsCmd.Flags().Int("timeout", 0, "Download timeout in seconds (0 = no timeout)") logsCmd.Flags().String("summary-file", "summary.json", "Path to write the summary JSON file relative to output directory (use empty string to disable)") logsCmd.MarkFlagsMutuallyExclusive("firewall", "no-firewall") diff --git a/pkg/cli/mcp_add.go b/pkg/cli/mcp_add.go index 0a140801f66..04080f5122d 100644 --- a/pkg/cli/mcp_add.go +++ b/pkg/cli/mcp_add.go @@ -315,6 +315,7 @@ This command searches the MCP registry for the specified server, adds it to the and automatically compiles the workflow. If the tool already exists, the command will fail. When called with no arguments, it will show a list of available MCP servers from the registry. +When called with only a workflow argument, it will show an error asking for a server name. The workflow-id-or-file can be: - A workflow ID (basename without .md extension, e.g., "weekly-research")