Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions cmd/gh-aw/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ This command only works with workflows that have workflow_dispatch triggers.
gh aw run daily-perf-improver --auto-merge-prs # Auto-merge any PRs created during execution
gh aw run daily-perf-improver -F name=value -F env=prod # Pass workflow inputs
gh aw run daily-perf-improver --push # Commit and push workflow files before running
gh aw run daily-perf-improver --dry-run # Validate without actually running
gh aw run daily-perf-improver --dry-run # Validate without triggering execution on GitHub Actions
gh aw run daily-perf-improver --json # Output results in JSON format`,
Args: cobra.ArbitraryArgs,
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -706,7 +706,7 @@ Use "` + string(constants.CLIExtensionPrefix) + ` help all" to show help for all
cli.RegisterEngineFlagCompletion(initCmd)

// Add flags to new command
newCmd.Flags().BoolP("force", "f", false, "Overwrite existing files without confirmation")
newCmd.Flags().BoolP("force", "f", false, "Overwrite existing workflow files without confirmation")
newCmd.Flags().BoolP("interactive", "i", false, "Launch interactive workflow creation wizard")
newCmd.Flags().StringP("engine", "e", "", "Override AI engine (copilot, claude, codex, gemini, crush)")
cli.RegisterEngineFlagCompletion(newCmd)
Expand Down Expand Up @@ -746,7 +746,7 @@ Use "` + string(constants.CLIExtensionPrefix) + ` help all" to show help for all
compileCmd.Flags().Bool("no-check-update", false, "Skip checking for gh-aw updates")
compileCmd.Flags().String("schedule-seed", "", "Override the repository slug (owner/repo) used as seed for fuzzy schedule scattering (e.g., \"github/gh-aw\"). Bypasses git remote detection entirely. Use this when your git remote is not named \"origin\" and you have multiple remotes configured")
compileCmd.Flags().Bool("staged", false, "Force all safe-outputs into staged mode")
compileCmd.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")
compileCmd.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.")
compileCmd.Flags().Bool("validate-images", false, "Require Docker to be available for container image validation. Without this flag, container image validation is silently skipped when Docker is not installed or the daemon is not running")
compileCmd.Flags().String("prior-manifest-file", "", "Path to a JSON file containing pre-cached gh-aw-manifests (map[lockFile]*GHAWManifest); used by the MCP server to supply a tamper-proof manifest baseline captured at startup")
compileCmd.Flags().Bool("ghes", false, "Enable GitHub Enterprise Server (GHES) compatibility mode: emit upload-artifact@v3 and download-artifact@v3 instead of the latest v7/v8 which are not supported on GHES. Overrides the aw.json ghes field")
Expand Down Expand Up @@ -787,12 +787,12 @@ Use "` + string(constants.CLIExtensionPrefix) + ` help all" to show help for all
runCmd.Flags().StringP("engine", "e", "", "Override AI engine (copilot, claude, codex, gemini, crush)")
runCmd.Flags().StringP("repo", "r", "", "Target repository ([HOST/]owner/repo format). Defaults to current repository")
runCmd.Flags().String("ref", "", "Branch or tag name to run the workflow on (default: current branch)")
runCmd.Flags().Bool("auto-merge-prs", false, "Auto-merge any pull requests created during the workflow execution")
runCmd.Flags().Bool("auto-merge-prs", false, "Auto-merge any pull requests created during execution")
runCmd.Flags().StringArrayP("raw-field", "F", []string{}, "Add a string parameter in key=value format (can be used multiple times)")
runCmd.Flags().Bool("push", false, "Commit and push workflow files (including transitive imports) before running")
runCmd.Flags().Bool("dry-run", false, "Validate workflow without actually triggering execution on GitHub Actions")
runCmd.Flags().BoolP("json", "j", false, "Output results in JSON format")
runCmd.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")
runCmd.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.")
// Register completions for run command
runCmd.ValidArgsFunction = cli.CompleteWorkflowNames
cli.RegisterEngineFlagCompletion(runCmd)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# ADR-42832: Adopt `--no-X` Flag Convention and Enforce `add-wizard` Flag Parity

**Date**: 2026-07-02
**Status**: Draft
**Deciders**: pelikhan (automated inspection via copilot-swe-agent)

---

### Context

The `gh-aw` CLI had grown inconsistently: most boolean negation flags followed a `--no-X` prefix (e.g., `--no-fix`, `--no-compile`, `--no-actions`), but one flag — `--disable-codemod` — used a `--disable-X` prefix introduced at a different time. This made the CLI surface feel non-uniform to users who relied on tab-completion and `--help` output.

Separately, the `add-wizard` command shared the same underlying workflow installation logic as `add` and `deploy`, but its `AddInteractiveConfig` struct was missing the `Name`, `Force`, `AppendText`, and `DisableSecurityScanner` fields. Those fields were hardcoded to zero values when `add-wizard` called into `AddResolvedWorkflows`, silently ignoring flags a user might expect to work by analogy with `add`/`deploy`.

An automated CLI consistency inspection across 29 files identified these as the two highest-severity issues in the codebase's CLI surface.

### Decision

We will rename `--disable-codemod` to `--no-codemod` in the `fix` and `upgrade` commands, matching the `--no-X` convention used everywhere else. The old flag name is not preserved as an alias (a clean break). We will also expand `AddInteractiveConfig` to include `Name`, `Force`, `AppendText`, and `DisableSecurityScanner`, register those flags on `add-wizard`, and propagate them through to `AddResolvedWorkflows` so the interactive wizard has full parity with the direct `add`/`deploy` commands.

### Alternatives Considered

#### Alternative 1: Keep `--disable-codemod` and add `--no-codemod` as an alias

Both flag names would be accepted. The inconsistency would remain visible in `--help` output and completion lists, but existing scripts using `--disable-codemod` would not break. Rejected because maintaining two names for the same flag adds ongoing documentation burden and extends the period of inconsistency indefinitely.

#### Alternative 2: Keep `--disable-codemod` unchanged and only fix documentation

Leave the flag name as-is and update only prose that mentioned it. This eliminates the breakage risk but permanently encodes the exception into the CLI contract. Rejected because the `--disable-X` outlier will confuse future contributors adding new flags, who will need to decide which convention to follow.

#### Alternative 3: Extend `AddInteractiveConfig` but not register the new flags on `add-wizard`

Propagate the struct fields but do not expose the flags at the CLI layer, deferring the UX decision. Rejected because half-wired flags (struct fields with no CLI entry point) are worse than no fields at all — they create dead code and false impressions that the feature is accessible.

### Consequences

#### Positive
- The CLI flag surface is now internally consistent: all boolean negation flags use `--no-X`.
- `add-wizard` users can now pass `--name`, `--force`, `--append`, and `--no-security-scanner` with the same semantics as `add`/`deploy`.
- The `AddInteractiveConfig` struct accurately reflects the full set of options the wizard supports, making the code easier to audit and extend.

#### Negative
- Renaming `--disable-codemod` to `--no-codemod` is a breaking change for any scripts or CI configurations that used the old flag name. No deprecation alias was added.
- `add-wizard` now accepts more flags, which increases its test surface and the risk of future divergence if `add`/`deploy` flags are added without a corresponding update to `add-wizard`.

#### Neutral
- Downstream documentation (docs/src/content/docs/setup/cli.md) was updated in the same PR to reflect the renamed flag and the corrected `--push` behaviour description.
- The `disable-security-scanner` legacy alias on `add`, `deploy`, and `trial` is preserved as a hidden flag; this PR did not extend that pattern to `add-wizard`'s new `--no-security-scanner` flag.

---

*ADR created by [adr-writer agent]. Review and finalize before changing status from Draft to Accepted.*
16 changes: 8 additions & 8 deletions docs/src/content/docs/setup/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Use `gh aw version` to print the current version.

### The `--push` Flag

`gh aw run --push` stages all changes, commits them, and pushes before dispatching the workflow. It requires a clean working directory.
`gh aw run --push` stages workflow files only (including transitive imports), commits them, and pushes before dispatching the workflow. It does not require a clean working directory, but will abort if there are already staged files that are not part of the workflow set — commit or unstage those files before using `--push`.

For `init`, `update`, and `upgrade`, use `--create-pull-request` instead.

Expand All @@ -140,7 +140,7 @@ gh aw init --engine claude # Skip Copilot-specific artifacts
gh aw init --no-mcp # Skip MCP server integration
gh aw init --no-skill # Skip dispatcher skill creation
gh aw init --no-agent # Skip custom agent creation
gh aw init --codespaces "" # Configure Codespaces for current repo only
gh aw init --codespaces "" # Configure Codespaces for current repository only
gh aw init --codespaces repo1,repo2 # Configure Codespaces with additional repos
gh aw init --completions # Install shell completions
gh aw init --create-pull-request # Initialize and open a pull request
Expand Down Expand Up @@ -265,9 +265,9 @@ gh aw fix my-workflow --write # Fix specific workflow
gh aw fix --list-codemods # List available codemods
```

**Options:** `--dir/-d`, `--disable-codemod`, `--list-codemods`, `--write`
**Options:** `--dir/-d`, `--no-codemod`, `--list-codemods`, `--write`

Use `--disable-codemod` (repeatable) to skip specific codemod IDs by name.
Use `--no-codemod` (repeatable) to skip specific codemod IDs by name.

Available codemods include:

Expand Down Expand Up @@ -708,11 +708,11 @@ gh aw upgrade --audit --json # Dependency audit in JSON format
gh aw upgrade --org my-org --create-issue --yes # Auto-accept per-repo confirmations (required in CI)
```

**Options:** `--dir/-d`, `--no-fix`, `--no-actions`, `--no-compile`, `--disable-codemod`, `--create-pull-request`, `--create-issue`, `--org`, `--repos`, `--yes/-y`, `--audit`, `--json/-j`, `--approve`, `--pre-releases`
**Options:** `--dir/-d`, `--no-fix`, `--no-actions`, `--no-compile`, `--no-codemod`, `--create-pull-request`, `--create-issue`, `--org`, `--repos`, `--yes/-y`, `--audit`, `--json/-j`, `--approve`, `--pre-releases`

Org mode (`--org`) previews or creates upgrade pull requests across every repository in an organization. Use `--repos` to limit org mode to repositories matching one or more glob patterns, `--create-issue` to open an issue in each org repository with agentic workflows (requires `--org`), and `--yes/-y` to auto-accept org-mode create confirmations (required in CI).

Use `--disable-codemod` (repeatable) to skip specific codemod IDs during the embedded fix step. This flag is ignored when `--no-fix` is set.
Use `--no-codemod` (repeatable) to skip specific codemod IDs during the embedded fix step. This flag is ignored when `--no-fix` is set.

#### `env`

Expand Down Expand Up @@ -822,15 +822,15 @@ gh aw completion fish # Generate fish script
gh aw completion powershell # Generate powershell script
```

**Subcommands:** `install`, `uninstall`, `bash`, `zsh`, `fish`, `powershell`. See [Shell Completions](#shell-completions).
**Subcommands:** `install`, `uninstall`. **Shell values:** `bash`, `zsh`, `fish`, `powershell`. See [Shell Completions](#shell-completions).

#### `project`

Create and manage GitHub Projects V2 boards.

##### `project new`

Create a new GitHub Project V2 owned by a user or organization with optional repository linking.
Create a new GitHub Projects V2 board owned by a user or organization with optional repository linking.

```bash wrap
gh aw project new "My Project" --owner @me # Create user project
Expand Down
8 changes: 4 additions & 4 deletions pkg/cli/add_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Workflow specifications:
- Four+ parts: "owner/repo/workflows/workflow-name.md[@version]" (requires explicit .md extension)
- GitHub URL: "https://github.com/owner/repo/blob/branch/path/to/workflow.md"
- Arbitrary URL: "https://example.com/workflow.md" (fetches and dispatches on Content-Type)
- text/markdown → treated as a gh-aw workflow markdown file
- text/markdown → treated as a gh-aw workflow Markdown file
- application/json → converted from a JSON workflow definition
- Local file: "./path/to/workflow.md" (adds a workflow from local filesystem)
- Local wildcard: "./*.md" or "./dir/*.md" (adds all .md files matching pattern)
Expand Down Expand Up @@ -179,7 +179,7 @@ func registerAddCommandFlags(cmd *cobra.Command) {
cmd.Flags().BoolP("force", "f", false, "Overwrite existing workflow files without confirmation")

// Add append flag to add command
cmd.Flags().String("append", "", "Append extra content to the end of agentic workflow on installation")
cmd.Flags().String("append", "", "Append extra content to the end of an agentic workflow on installation")

// Add no-gitattributes flag to add command
cmd.Flags().Bool("no-gitattributes", false, "Skip updating .gitattributes file")
Expand All @@ -194,8 +194,8 @@ func registerAddCommandFlags(cmd *cobra.Command) {
cmd.Flags().String("stop-after", "", "Override stop-after value in the workflow (e.g., '+48h', '2025-12-31 23:59:59')")

// Add no-security-scanner flag to add command (--disable-security-scanner is kept as an undocumented alias)
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().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")

// Register completions for add command
Expand Down
8 changes: 4 additions & 4 deletions pkg/cli/add_interactive_git.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ func (c *AddInteractiveConfig) createWorkflowPRAndConfigureSecret(ctx context.Co
Verbose: c.Verbose,
Quiet: true,
EngineOverride: c.EngineOverride,
Name: "",
Force: false,
AppendText: "",
Name: c.Name,
Force: c.Force,
AppendText: c.AppendText,
CreatePR: true,
NoGitattributes: c.NoGitattributes,
WorkflowDir: c.WorkflowDir,
NoStopAfter: c.NoStopAfter,
StopAfter: c.StopAfter,
DisableSecurityScanner: false,
DisableSecurityScanner: c.DisableSecurityScanner,
AddCopilotRequestsPermission: c.UseCopilotRequests,
}
result, err := AddResolvedWorkflows(ctx, c.WorkflowSpecs, c.resolvedWorkflows, opts)
Expand Down
26 changes: 15 additions & 11 deletions pkg/cli/add_interactive_orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@ var addInteractiveLog = logger.New("cli:add_interactive")

// AddInteractiveConfig holds configuration for interactive add mode
type AddInteractiveConfig struct {
Ctx context.Context // Context for cancellation (Ctrl-C handling)
WorkflowSpecs []string
Verbose bool
EngineOverride string
NoGitattributes bool
WorkflowDir string
NoStopAfter bool
StopAfter string
SkipWorkflowRun bool
SkipSecret bool // Skip the API secret prompt (useful when secret is set at org level)
RepoOverride string // owner/repo format, if user provides it
Ctx context.Context // Context for cancellation (Ctrl-C handling)
WorkflowSpecs []string
Verbose bool
EngineOverride string
Name string
Force bool
AppendText string
NoGitattributes bool
WorkflowDir string
NoStopAfter bool
StopAfter string
DisableSecurityScanner bool
SkipWorkflowRun bool
SkipSecret bool // Skip the API secret prompt (useful when secret is set at org level)
RepoOverride string // owner/repo format, if user provides it

// UseCopilotRequests indicates the user chose org-billing (copilot-requests) auth
// instead of a PAT when setting up the Copilot engine during the wizard.
Expand Down
Loading
Loading