From 52825fc91573b0d760dc9e04b99b512784a8f6dc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Jun 2026 15:07:39 +0000 Subject: [PATCH 1/4] Initial plan From ea47cadb9bb5f4cd33add819d42ed06f9f938ff4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Jun 2026 15:24:51 +0000 Subject: [PATCH 2/4] fix: align CLI help grouping and flag consistency Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- cmd/gh-aw/command_groups_test.go | 4 ++++ cmd/gh-aw/main.go | 16 +++++++++------- docs/src/content/docs/setup/cli.md | 14 +++++++------- pkg/cli/env_command.go | 4 ++-- pkg/cli/fix_command.go | 2 +- pkg/cli/flags.go | 2 +- pkg/cli/flags_test.go | 26 ++++++++++++++++++++++++++ pkg/cli/forecast_command.go | 2 +- pkg/cli/logs_command.go | 2 +- pkg/cli/logs_command_test.go | 3 ++- pkg/cli/logs_filtering_test.go | 7 ++++--- pkg/cli/trial_command.go | 13 ++----------- pkg/cli/upgrade_command.go | 2 +- 13 files changed, 61 insertions(+), 36 deletions(-) diff --git a/cmd/gh-aw/command_groups_test.go b/cmd/gh-aw/command_groups_test.go index 9d2d5d4dbbb..4e1e1efa4dd 100644 --- a/cmd/gh-aw/command_groups_test.go +++ b/cmd/gh-aw/command_groups_test.go @@ -46,7 +46,11 @@ func TestCommandGroupAssignments(t *testing.T) { {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: "outcomes command in analysis group", commandName: "outcomes", expectedGroup: "analysis", shouldHaveGroup: true}, {name: "checks command in analysis group", commandName: "checks", expectedGroup: "analysis", shouldHaveGroup: true}, + // Hidden commands should still be grouped so they appear in the correct + // section when explicitly shown (for example in full help/test contexts). + {name: "view command in analysis group", commandName: "view", expectedGroup: "analysis", shouldHaveGroup: true}, {name: "experiments command in analysis group", commandName: "experiments", expectedGroup: "analysis", shouldHaveGroup: true}, // Utilities diff --git a/cmd/gh-aw/main.go b/cmd/gh-aw/main.go index 238d3a7d21a..06e8095b729 100644 --- a/cmd/gh-aw/main.go +++ b/cmd/gh-aw/main.go @@ -90,8 +90,9 @@ Common Tasks: gh aw new my-workflow # Create your first workflow gh aw compile # Compile all workflows gh aw run my-workflow # Execute a workflow + gh aw status # Check workflow status gh aw logs my-workflow # View execution logs - gh aw audit # Debug a failed run + gh aw audit # Audit and compare workflow runs For detailed help on any command, use: gh aw [command] --help`, @@ -725,14 +726,14 @@ Use "` + string(constants.CLIExtensionPrefix) + ` help all" to show help for all compileCmd.Flags().Bool("purge", false, "Delete .lock.yml files that were not regenerated during compilation (only when no specific files are specified)") compileCmd.Flags().Bool("strict", false, "Override frontmatter to enforce strict mode validation for all workflows (enforces action pinning, network config, safe-outputs, refuses write permissions and deprecated fields). Note: Workflows default to strict mode unless frontmatter sets strict: false") compileCmd.Flags().Bool("trial", false, "Enable trial mode compilation (modifies workflows for trial execution)") - compileCmd.Flags().String("logical-repo", "", "Repository to simulate workflow execution against (for trial mode)") + compileCmd.Flags().StringP("logical-repo", "l", "", "Repository to simulate workflow execution against (for trial mode)") compileCmd.Flags().Bool("use-samples", false, "Hidden: replace the agentic 'Execute coding agent' step with a deterministic driver that replays the workflow's safe-outputs `samples` frontmatter entries through the safe-outputs MCP server. Used to make end-to-end tests deterministic.") _ = compileCmd.Flags().MarkHidden("use-samples") compileCmd.Flags().Bool("dependabot", false, "Generate dependency manifests (package.json, requirements.txt, go.mod) and Dependabot config when dependencies are detected") - compileCmd.Flags().Bool("force", false, "Force overwrite of existing dependency files (e.g., dependabot.yml)") + compileCmd.Flags().BoolP("force", "f", false, "Force overwrite of existing dependency files (e.g., dependabot.yml)") compileCmd.Flags().Bool("refresh-stop-time", false, "Force regeneration of stop-after times instead of preserving existing values from lock files") compileCmd.Flags().Bool("force-refresh-action-pins", false, "Force refresh of action pins by clearing the cache and resolving all action SHAs from GitHub API") - compileCmd.Flags().Bool("allow-action-refs", false, "Allow unresolved action refs and emit warnings instead of failing compilation") + compileCmd.Flags().Bool("allow-action-refs", false, "Allow unresolved action refs and emit warnings instead of failing validation") compileCmd.Flags().Bool("zizmor", false, "Run zizmor security scanner on generated .lock.yml files") compileCmd.Flags().Bool("poutine", false, "Run poutine security scanner on generated .lock.yml files") compileCmd.Flags().Bool("actionlint", false, "Run actionlint linter on generated .lock.yml files") @@ -808,6 +809,7 @@ Use "` + string(constants.CLIExtensionPrefix) + ` help all" to show help for all auditCmd := cli.NewAuditCommand() viewCmd := cli.NewViewCommand() healthCmd := cli.NewHealthCommand() + outcomesCmd := cli.NewOutcomesCommand() mcpServerCmd := cli.NewMCPServerCommand() prCmd := cli.NewPRCommand() secretsCmd := cli.NewSecretsCommand() @@ -844,8 +846,6 @@ Use "` + string(constants.CLIExtensionPrefix) + ` help all" to show help for all mcpCmd.GroupID = "development" fixCmd.GroupID = "development" domainsCmd.GroupID = "development" - statusCmd.GroupID = "analysis" - listCmd.GroupID = "analysis" // Execution Commands runCmd.GroupID = "execution" @@ -858,7 +858,10 @@ Use "` + string(constants.CLIExtensionPrefix) + ` help all" to show help for all auditCmd.GroupID = "analysis" viewCmd.GroupID = "analysis" healthCmd.GroupID = "analysis" + outcomesCmd.GroupID = "analysis" checksCmd.GroupID = "analysis" + statusCmd.GroupID = "analysis" + listCmd.GroupID = "analysis" experimentsCmd.GroupID = "analysis" forecastCmd.GroupID = "analysis" @@ -887,7 +890,6 @@ Use "` + string(constants.CLIExtensionPrefix) + ` help all" to show help for all rootCmd.AddCommand(listCmd) rootCmd.AddCommand(enableCmd) rootCmd.AddCommand(disableCmd) - outcomesCmd := cli.NewOutcomesCommand() rootCmd.AddCommand(logsCmd) rootCmd.AddCommand(auditCmd) rootCmd.AddCommand(viewCmd) diff --git a/docs/src/content/docs/setup/cli.md b/docs/src/content/docs/setup/cli.md index 93aa598ba4f..8e7d9aaaca7 100644 --- a/docs/src/content/docs/setup/cli.md +++ b/docs/src/content/docs/setup/cli.md @@ -20,7 +20,7 @@ The `gh aw` CLI extension enables developers to create, manage, and execute AI-p | [`gh aw run`](#run) | Execute workflows immediately in GitHub Actions | | [`gh aw status`](#status) | Check current state of all workflows | | [`gh aw logs`](#logs) | Download and analyze workflow logs | -| [`gh aw audit`](#audit) | Debug a failed workflow run | +| [`gh aw audit`](#audit) | Audit and compare workflow runs | ## Installation @@ -168,7 +168,7 @@ Add workflows from The Agentics collection or other repositories to `.github/wor ```bash wrap gh aw add githubnext/agentics/ci-doctor # Add single workflow gh aw add githubnext/agentics/ci-doctor@v1.0.0 # Add specific version -gh aw add githubnext/agentics/ci-doctor --dir shared # Organize in subdirectory +gh aw add githubnext/agentics/ci-doctor --dir .github/workflows/shared # Organize in subdirectory gh aw add githubnext/agentics/ci-doctor --create-pull-request # Create PR instead of commit gh aw add https://example.com/workflows/my-workflow.md # Arbitrary HTTPS URL (markdown) gh aw add https://example.com/workflows/my-workflow.json # Arbitrary HTTPS URL (JSON workflow definition) @@ -293,7 +293,7 @@ gh aw compile --purge # Remove orphaned .lock.yml files If the repository root contains an [`aw.yml` manifest](/gh-aw/reference/aw-yml-package-manifest/), `gh aw compile` validates it before compiling workflows. -**Options:** `--action-mode`, `--action-tag`, `--actionlint`, `--actions-repo`, `--allow-action-refs`, `--approve`, `--dependabot`, `--dir/-d`, `--engine/-e`, `--fail-fast`, `--fix`, `--force`, `--force-refresh-action-pins`, `--gh-aw-ref`, `--ghes`, `--json/-j`, `--logical-repo`, `--no-check-update`, `--no-emit`, `--poutine`, `--purge`, `--refresh-stop-time`, `--runner-guard`, `--schedule-seed`, `--show-all`, `--staged`, `--stats`, `--strict`, `--trial`, `--validate`, `--validate-images`, `--watch/-w`, `--zizmor` +**Options:** `--action-mode`, `--action-tag`, `--actionlint`, `--actions-repo`, `--allow-action-refs`, `--approve`, `--dependabot`, `--dir/-d`, `--engine/-e`, `--fail-fast`, `--fix`, `--force/-f`, `--force-refresh-action-pins`, `--gh-aw-ref`, `--ghes`, `--json/-j`, `--logical-repo/-l`, `--no-check-update`, `--no-emit`, `--poutine`, `--purge`, `--refresh-stop-time`, `--runner-guard`, `--schedule-seed`, `--show-all`, `--staged`, `--stats`, `--strict`, `--trial`, `--validate`, `--validate-images`, `--watch/-w`, `--zizmor` **`--gh-aw-ref` flag:** Convenience alias for `--action-mode release --action-tag `. Accepts a branch name, tag, or commit SHA targeting the `github/gh-aw` repository. Branch and tag names are resolved to their full commit SHA at compile time, so the baked-in reference is immutable and reproducible. Useful for E2E-testing workflows compiled against a specific gh-aw revision. @@ -466,7 +466,7 @@ echo "1234567890" | gh aw logs --stdin --engine claude cat run-ids.txt | gh aw logs --stdin --repo owner/repo # required for bare numeric IDs ``` -**Options:** `--after-run-id`, `--artifacts`, `--before-run-id`, `--cache-before`, `--count/-c`, `--end-date`, `--engine/-e`, `--filtered-integrity`, `--firewall`, `--format`, `--json/-j`, `--last`, `--no-firewall`, `--no-staged`, `--output/-o`, `--parse`, `--ref`, `--report-file`, `--repo/-r`, `--safe-output`, `--start-date`, `--stdin`, `--summary-file`, `--timeout`, `--tool-graph`, `--train` +**Options:** `--after-run-id`, `--artifacts`, `--before-run-id`, `--cache-before`, `--count/-c`, `--end-date`, `--engine`, `--filtered-integrity`, `--firewall`, `--format`, `--json/-j`, `--last`, `--no-firewall`, `--no-staged`, `--output/-o`, `--parse`, `--ref`, `--report-file`, `--repo/-r`, `--safe-output`, `--start-date`, `--stdin`, `--summary-file`, `--timeout`, `--tool-graph`, `--train` #### `audit` @@ -591,7 +591,7 @@ Maps PR check rollups to one of the following normalized states: `success`, `fai #### `forecast` `[EXPERIMENTAL]` -Forecast AI Credit (AIC) usage and costs for agentic workflows using recent run history and Monte Carlo simulation. +Forecast AI Credit (AIC) usage for agentic workflows using recent run history and Monte Carlo simulation. ```bash wrap gh aw forecast # Forecast all workflows (monthly) @@ -716,7 +716,7 @@ gh aw env get org-defaults.yml --scope org --org my-org gh aw env get ent-defaults.yml --scope ent --enterprise my-enterprise ``` -**Options:** `--scope`, `--repo`, `--org`, `--enterprise` +**Options:** `--scope`, `--repo/-r`, `--org`, `--enterprise` ##### `env update [file]` @@ -728,7 +728,7 @@ gh aw env update defaults.yml --scope org --org my-org --dry-run gh aw env update defaults.yml --scope ent --enterprise my-enterprise --yes ``` -**Options:** `--scope` (required), `--repo`, `--org`, `--enterprise`, `--yes/-y`, `--dry-run` +**Options:** `--scope` (required), `--repo/-r`, `--org`, `--enterprise`, `--yes/-y`, `--dry-run` ### Advanced diff --git a/pkg/cli/env_command.go b/pkg/cli/env_command.go index e89e09374e7..b910fbbd305 100644 --- a/pkg/cli/env_command.go +++ b/pkg/cli/env_command.go @@ -159,7 +159,7 @@ Scope resolution: } cmd.Flags().StringVar(&scope, "scope", "", "Variable scope (repo|org|ent). Defaults to repo") - cmd.Flags().StringVar(&repo, "repo", "", "Target repository in owner/repo format") + cmd.Flags().StringVarP(&repo, "repo", "r", "", "Target repository in owner/repo format. Defaults to current repository") cmd.Flags().StringVar(&org, "org", "", "Target organization (required for --scope org unless inferable from --repo/current repo)") cmd.Flags().StringVar(&enterprise, "enterprise", "", "Target enterprise slug (required for --scope ent)") return cmd @@ -198,7 +198,7 @@ Scope and flag behavior: } cmd.Flags().StringVar(&scope, "scope", "", "Variable scope (repo|org|ent)") - cmd.Flags().StringVar(&repo, "repo", "", "Target repository in owner/repo format") + cmd.Flags().StringVarP(&repo, "repo", "r", "", "Target repository in owner/repo format. Defaults to current repository") cmd.Flags().StringVar(&org, "org", "", "Target organization (required for --scope org unless inferable from --repo/current repo)") cmd.Flags().StringVar(&enterprise, "enterprise", "", "Target enterprise slug (required for --scope ent)") cmd.Flags().BoolVarP(&yes, "yes", "y", false, "Skip confirmation prompt") diff --git a/pkg/cli/fix_command.go b/pkg/cli/fix_command.go index 820e4fc99a0..7e83abb438c 100644 --- a/pkg/cli/fix_command.go +++ b/pkg/cli/fix_command.go @@ -82,7 +82,7 @@ all steps and additionally: cmd.Flags().Bool("write", false, "Write changes to files (without this flag, no changes are made)") cmd.Flags().Bool("list-codemods", false, "List all available codemods and exit") cmd.Flags().StringP("dir", "d", "", "Workflow directory (default: .github/workflows)") - cmd.Flags().StringSlice("disable-codemod", nil, "Disable specific codemod IDs (repeatable)") + cmd.Flags().StringSlice("disable-codemod", nil, "Disable specific codemod IDs during the fix step (repeatable)") // Register completions cmd.ValidArgsFunction = CompleteWorkflowNames diff --git a/pkg/cli/flags.go b/pkg/cli/flags.go index cb89f671320..ee683971b49 100644 --- a/pkg/cli/flags.go +++ b/pkg/cli/flags.go @@ -17,7 +17,7 @@ func addEngineFlag(cmd *cobra.Command) { // addEngineFilterFlag adds the --engine/-e flag to a command for filtering. // This flag allows filtering results by AI engine type. func addEngineFilterFlag(cmd *cobra.Command) { - cmd.Flags().StringP("engine", "e", "", engineFlagUsage("Filter logs by AI engine")) + cmd.Flags().String("engine", "", engineFlagUsage("Filter logs by AI engine")) } // addRepoFlag adds the --repo/-r flag to a command. diff --git a/pkg/cli/flags_test.go b/pkg/cli/flags_test.go index 0b5a05e8e92..df94a2e5f0a 100644 --- a/pkg/cli/flags_test.go +++ b/pkg/cli/flags_test.go @@ -59,6 +59,14 @@ func TestShortFlagConsistency(t *testing.T) { shouldExist: true, description: "update should have force short flag", }, + { + name: "compile command has -f for --force", + shortFlag: "f", + longFlag: "force", + commandSetup: func() *cobra.Command { return createCompileCommandStub() }, + shouldExist: true, + description: "compile should have force short flag", + }, // -F flag (raw-field in run command) { @@ -147,6 +155,14 @@ func TestShortFlagConsistency(t *testing.T) { shouldExist: true, description: "update should have dir short flag", }, + { + name: "compile command has -l for --logical-repo", + shortFlag: "l", + longFlag: "logical-repo", + commandSetup: func() *cobra.Command { return createCompileCommandStub() }, + shouldExist: true, + description: "compile should have logical-repo short flag", + }, // -c flag (count) - should only be in logs command { @@ -175,6 +191,14 @@ func TestShortFlagConsistency(t *testing.T) { shouldExist: true, description: "disable should have repo short flag", }, + { + name: "logs command does not have -e for --engine", + shortFlag: "e", + longFlag: "engine", + commandSetup: func() *cobra.Command { return NewLogsCommand() }, + shouldExist: false, + description: "logs should not have engine short flag", + }, // -w flag (watch) { @@ -233,8 +257,10 @@ func TestShortFlagConsistency(t *testing.T) { func createCompileCommandStub() *cobra.Command { cmd := &cobra.Command{Use: "compile"} cmd.Flags().StringP("engine", "e", "", "Override AI engine") + cmd.Flags().BoolP("force", "f", false, "Force overwrite") cmd.Flags().BoolP("watch", "w", false, "Watch for changes") cmd.Flags().StringP("dir", "d", "", "Workflow directory") + cmd.Flags().StringP("logical-repo", "l", "", "Repository to simulate") cmd.Flags().BoolP("json", "j", false, "Output results in JSON format") return cmd } diff --git a/pkg/cli/forecast_command.go b/pkg/cli/forecast_command.go index 38e6b0bf9b8..40e8839368a 100644 --- a/pkg/cli/forecast_command.go +++ b/pkg/cli/forecast_command.go @@ -35,7 +35,7 @@ type ForecastConfig struct { func NewForecastCommand() *cobra.Command { cmd := &cobra.Command{ Use: "forecast [workflow]...", - Short: "Forecast AI Credit usage and costs for agentic workflows (experimental)", + Short: "[EXPERIMENTAL] Forecast AI Credit (AIC) usage for agentic workflows", Long: `[EXPERIMENTAL] Forecast AI Credit (AIC) usage for agentic workflows by sampling recent run history and projecting forward on a per-week or per-month basis. diff --git a/pkg/cli/logs_command.go b/pkg/cli/logs_command.go index 947a1386cae..a8680f410b5 100644 --- a/pkg/cli/logs_command.go +++ b/pkg/cli/logs_command.go @@ -31,7 +31,7 @@ func NewLogsCommand() *cobra.Command { logsCmd := &cobra.Command{ Use: "logs [workflow]", - Short: "Download and analyze agentic workflow logs with aggregated metrics", + Short: "Download and analyze agentic workflow logs and artifacts", Long: fmt.Sprintf(`Download and analyze agentic workflow logs and artifacts from GitHub Actions. This command fetches workflow runs, downloads their artifacts, and extracts them into diff --git a/pkg/cli/logs_command_test.go b/pkg/cli/logs_command_test.go index 297ac96c3db..f4e4bd5d1d9 100644 --- a/pkg/cli/logs_command_test.go +++ b/pkg/cli/logs_command_test.go @@ -17,7 +17,7 @@ func TestNewLogsCommand(t *testing.T) { require.NotNil(t, cmd, "NewLogsCommand should not return nil") assert.Equal(t, "logs [workflow]", cmd.Use, "Command use should be 'logs [workflow]'") - assert.Equal(t, "Download and analyze agentic workflow logs with aggregated metrics", cmd.Short, "Command short description should match") + assert.Equal(t, "Download and analyze agentic workflow logs and artifacts", cmd.Short, "Command short description should match") assert.Contains(t, cmd.Long, "Download and analyze agentic workflow logs", "Command long description should contain expected text") assert.Contains(t, cmd.Example, "logs --cache-before -1w", "Cache maintenance examples should use the cache-before flag name") @@ -40,6 +40,7 @@ func TestNewLogsCommand(t *testing.T) { // Check engine flag engineFlag := flags.Lookup("engine") assert.NotNil(t, engineFlag, "Should have 'engine' flag") + assert.Empty(t, engineFlag.Shorthand, "Engine filter flag should not have shorthand") // Check firewall flags firewallFlag := flags.Lookup("firewall") diff --git a/pkg/cli/logs_filtering_test.go b/pkg/cli/logs_filtering_test.go index 040972a5ac4..ee3e3bf3544 100644 --- a/pkg/cli/logs_filtering_test.go +++ b/pkg/cli/logs_filtering_test.go @@ -74,9 +74,10 @@ func TestLogsCommandFlags(t *testing.T) { t.Errorf("Expected engine flag default value to be empty, got: %s", engineFlag.DefValue) } - // Test that engine flag has the -e shorthand for consistency with other commands - if engineFlag.Shorthand != "e" { - t.Errorf("Expected engine flag shorthand to be 'e', got: %s", engineFlag.Shorthand) + // Engine filter flag intentionally has no shorthand to avoid conflicting + // semantics with override-style --engine/-e flags on mutating commands. + if engineFlag.Shorthand != "" { + t.Errorf("Expected engine flag shorthand to be empty, got: %s", engineFlag.Shorthand) } } diff --git a/pkg/cli/trial_command.go b/pkg/cli/trial_command.go index 1ab09ab3bcf..1d511523470 100644 --- a/pkg/cli/trial_command.go +++ b/pkg/cli/trial_command.go @@ -54,7 +54,6 @@ Trial results are saved both locally (in trials/ directory) and in the host repo logicalRepoSpec, _ := cmd.Flags().GetString("logical-repo") cloneRepoSpec, _ := cmd.Flags().GetString("clone-repo") hostRepoSpec, _ := cmd.Flags().GetString("host-repo") - repoSpec, _ := cmd.Flags().GetString("repo") deleteHostRepo, _ := cmd.Flags().GetBool("delete-host-repo-after") forceDeleteHostRepo, _ := cmd.Flags().GetBool("force-delete-host-repo-before") yes, _ := cmd.Flags().GetBool("yes") @@ -79,11 +78,6 @@ Trial results are saved both locally (in trials/ directory) and in the host repo trialLog.Printf("Trial options: dry_run=%v, repeat=%d, timeout_min=%d, auto_merge_prs=%v, logical_repo=%q, clone_repo=%q, host_repo=%q", dryRun, repeatCount, timeout, autoMergePRs, logicalRepoSpec, cloneRepoSpec, hostRepoSpec) } - // If --repo was used instead of --host-repo, use its value - if repoSpec != "" { - hostRepoSpec = repoSpec - } - opts := TrialOptions{ Repos: TrialRepoContext{ LogicalRepo: logicalRepoSpec, @@ -117,13 +111,11 @@ Trial results are saved both locally (in trials/ directory) and in the host repo cmd.Flags().String("clone-repo", "", "Clone the contents of the specified repository into the host repository before execution (useful for testing against actual repository state)") cmd.Flags().String("host-repo", "", "Custom host repository slug (defaults to '/gh-aw-trial'). Use '.' for current repository") - cmd.Flags().String("repo", "", "Alias for --host-repo: the repository where workflows are installed and run (note: different semantics from --repo in other commands)") - _ = cmd.Flags().MarkHidden("repo") // Hide alias to avoid semantic confusion with --repo in other commands cmd.Flags().Bool("delete-host-repo-after", false, "Delete the host repository after completion (kept by default)") cmd.Flags().Bool("force-delete-host-repo-before", false, "Force delete the host repository before creation if it already exists") cmd.Flags().BoolP("yes", "y", false, "Skip confirmation prompts") - cmd.Flags().Bool("dry-run", false, "Show what would be done without making any changes") - cmd.Flags().Int("timeout", 30, "Execution timeout in minutes") + cmd.Flags().Bool("dry-run", false, "Preview trial execution without applying any changes") + cmd.Flags().Int("timeout", 30, "Execution timeout in minutes (default: 30, 0 disables timeout)") cmd.Flags().String("trigger-context", "", "Trigger context URL (e.g., GitHub issue URL) for issue-triggered workflows") cmd.Flags().Int("repeat", 0, "Number of additional times to run after the initial execution (e.g., --repeat 3 runs 4 times total)") cmd.Flags().Bool("auto-merge-prs", false, "Auto-merge any pull requests created during trial execution") @@ -133,7 +125,6 @@ Trial results are saved both locally (in trials/ directory) and in the host repo cmd.Flags().Bool("no-security-scanner", false, "Disable security scanning of workflow markdown content") cmd.Flags().Bool("disable-security-scanner", false, "Disable security scanning of workflow markdown content") _ = cmd.Flags().MarkHidden("disable-security-scanner") - cmd.MarkFlagsMutuallyExclusive("host-repo", "repo") cmd.MarkFlagsMutuallyExclusive("logical-repo", "clone-repo") return cmd diff --git a/pkg/cli/upgrade_command.go b/pkg/cli/upgrade_command.go index f60e4f51b89..7ba5d643d71 100644 --- a/pkg/cli/upgrade_command.go +++ b/pkg/cli/upgrade_command.go @@ -155,7 +155,7 @@ This command always upgrades all Markdown files in .github/workflows.`, _ = cmd.Flags().MarkHidden("pr") // Hide the short alias from help output cmd.Flags().Bool("create-issue", false, "Open a GitHub issue in each org repository with agentic workflows (requires --org)") cmd.Flags().Bool("audit", false, "Check dependency health without performing upgrades") - cmd.Flags().Bool("pre-releases", false, "Include pre-release versions when checking for extension upgrades; prereleases are installed by exact tag") + cmd.Flags().Bool("pre-releases", false, "Include pre-release versions when checking for extension upgrades; pre-releases are installed by exact tag") cmd.Flags().Bool("approve", false, "Approve all safe update changes. When strict mode is active (the default), the compiler emits warnings for new restricted secrets or unapproved action additions/removals not present in the existing gh-aw-manifest. Use this flag to approve and skip safe update enforcement") cmd.Flags().Bool("skip-extension-upgrade", false, "Skip automatic extension upgrade (used internally to prevent recursion after upgrade)") _ = cmd.Flags().MarkHidden("skip-extension-upgrade") From ac818a48bac9b10f6d63f0a270b75cf390c3b628 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Jun 2026 15:31:58 +0000 Subject: [PATCH 3/4] test: add flag coverage for env and compile shorthand Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- cmd/gh-aw/compile_flags_test.go | 23 +++++++++++++++++++++++ pkg/cli/env_command.go | 4 ++-- pkg/cli/env_command_test.go | 8 ++++++++ pkg/cli/trial_command.go | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 cmd/gh-aw/compile_flags_test.go diff --git a/cmd/gh-aw/compile_flags_test.go b/cmd/gh-aw/compile_flags_test.go new file mode 100644 index 00000000000..1b15409819f --- /dev/null +++ b/cmd/gh-aw/compile_flags_test.go @@ -0,0 +1,23 @@ +//go:build !integration + +package main + +import "testing" + +func TestCompileCommandShortFlags(t *testing.T) { + forceFlag := compileCmd.Flags().Lookup("force") + if forceFlag == nil { + t.Fatal("expected --force flag on compile command") + } + if forceFlag.Shorthand != "f" { + t.Fatalf("expected --force shorthand to be -f, got -%s", forceFlag.Shorthand) + } + + logicalRepoFlag := compileCmd.Flags().Lookup("logical-repo") + if logicalRepoFlag == nil { + t.Fatal("expected --logical-repo flag on compile command") + } + if logicalRepoFlag.Shorthand != "l" { + t.Fatalf("expected --logical-repo shorthand to be -l, got -%s", logicalRepoFlag.Shorthand) + } +} diff --git a/pkg/cli/env_command.go b/pkg/cli/env_command.go index b910fbbd305..c105d8cc001 100644 --- a/pkg/cli/env_command.go +++ b/pkg/cli/env_command.go @@ -159,7 +159,7 @@ Scope resolution: } cmd.Flags().StringVar(&scope, "scope", "", "Variable scope (repo|org|ent). Defaults to repo") - cmd.Flags().StringVarP(&repo, "repo", "r", "", "Target repository in owner/repo format. Defaults to current repository") + cmd.Flags().StringVarP(&repo, "repo", "r", "", "Target repository in owner/repo format. When omitted, defaults to current repository") cmd.Flags().StringVar(&org, "org", "", "Target organization (required for --scope org unless inferable from --repo/current repo)") cmd.Flags().StringVar(&enterprise, "enterprise", "", "Target enterprise slug (required for --scope ent)") return cmd @@ -198,7 +198,7 @@ Scope and flag behavior: } cmd.Flags().StringVar(&scope, "scope", "", "Variable scope (repo|org|ent)") - cmd.Flags().StringVarP(&repo, "repo", "r", "", "Target repository in owner/repo format. Defaults to current repository") + cmd.Flags().StringVarP(&repo, "repo", "r", "", "Target repository in owner/repo format. When omitted, defaults to current repository") cmd.Flags().StringVar(&org, "org", "", "Target organization (required for --scope org unless inferable from --repo/current repo)") cmd.Flags().StringVar(&enterprise, "enterprise", "", "Target enterprise slug (required for --scope ent)") cmd.Flags().BoolVarP(&yes, "yes", "y", false, "Skip confirmation prompt") diff --git a/pkg/cli/env_command_test.go b/pkg/cli/env_command_test.go index be5add76282..1292b353f32 100644 --- a/pkg/cli/env_command_test.go +++ b/pkg/cli/env_command_test.go @@ -43,6 +43,14 @@ func TestNewEnvCommand(t *testing.T) { assert.Contains(t, updateCmd.Long, "--yes") assert.NotNil(t, updateCmd.Flags().Lookup("yes")) assert.NotNil(t, updateCmd.Flags().Lookup("dry-run")) + + getRepoFlag := getCmd.Flags().Lookup("repo") + require.NotNil(t, getRepoFlag) + assert.Equal(t, "r", getRepoFlag.Shorthand) + + updateRepoFlag := updateCmd.Flags().Lookup("repo") + require.NotNil(t, updateRepoFlag) + assert.Equal(t, "r", updateRepoFlag.Shorthand) } func TestResolveDefaultsTarget(t *testing.T) { diff --git a/pkg/cli/trial_command.go b/pkg/cli/trial_command.go index 1d511523470..0ec2e0da16e 100644 --- a/pkg/cli/trial_command.go +++ b/pkg/cli/trial_command.go @@ -115,7 +115,7 @@ Trial results are saved both locally (in trials/ directory) and in the host repo cmd.Flags().Bool("force-delete-host-repo-before", false, "Force delete the host repository before creation if it already exists") cmd.Flags().BoolP("yes", "y", false, "Skip confirmation prompts") cmd.Flags().Bool("dry-run", false, "Preview trial execution without applying any changes") - cmd.Flags().Int("timeout", 30, "Execution timeout in minutes (default: 30, 0 disables timeout)") + cmd.Flags().Int("timeout", 30, "Execution timeout in minutes (set to 0 to disable timeout)") cmd.Flags().String("trigger-context", "", "Trigger context URL (e.g., GitHub issue URL) for issue-triggered workflows") cmd.Flags().Int("repeat", 0, "Number of additional times to run after the initial execution (e.g., --repeat 3 runs 4 times total)") cmd.Flags().Bool("auto-merge-prs", false, "Auto-merge any pull requests created during trial execution") From b54a217404bcdb65985ddd99729bc3dd5c16edc9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:45:23 +0000 Subject: [PATCH 4/4] fix: update addEngineFilterFlag comment and align logs docs description Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- docs/src/content/docs/setup/cli.md | 2 +- pkg/cli/flags.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/src/content/docs/setup/cli.md b/docs/src/content/docs/setup/cli.md index 8e7d9aaaca7..0bb644a8052 100644 --- a/docs/src/content/docs/setup/cli.md +++ b/docs/src/content/docs/setup/cli.md @@ -19,7 +19,7 @@ The `gh aw` CLI extension enables developers to create, manage, and execute AI-p | [`gh aw list`](#list) | Quick listing of all workflows | | [`gh aw run`](#run) | Execute workflows immediately in GitHub Actions | | [`gh aw status`](#status) | Check current state of all workflows | -| [`gh aw logs`](#logs) | Download and analyze workflow logs | +| [`gh aw logs`](#logs) | Download and analyze agentic workflow logs and artifacts | | [`gh aw audit`](#audit) | Audit and compare workflow runs | ## Installation diff --git a/pkg/cli/flags.go b/pkg/cli/flags.go index ee683971b49..0d00d34536e 100644 --- a/pkg/cli/flags.go +++ b/pkg/cli/flags.go @@ -14,8 +14,9 @@ func addEngineFlag(cmd *cobra.Command) { cmd.Flags().StringP("engine", "e", "", engineFlagUsage("Override AI engine")) } -// addEngineFilterFlag adds the --engine/-e flag to a command for filtering. -// This flag allows filtering results by AI engine type. +// addEngineFilterFlag adds the --engine flag to a command for filtering. +// This flag allows filtering results by AI engine type. No shorthand is +// registered to avoid collision with the override-style --engine/-e flag. func addEngineFilterFlag(cmd *cobra.Command) { cmd.Flags().String("engine", "", engineFlagUsage("Filter logs by AI engine")) }