From 6359206e595ff1d0636baa4095e282c6587b71cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Jul 2026 15:18:34 +0000 Subject: [PATCH 1/6] Initial plan From 989e8a89472171dd9a119a0f90dd9e5a9045e2ec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Jul 2026 15:34:03 +0000 Subject: [PATCH 2/6] fix: CLI consistency improvements - align help text, add wizard flags, fix wording Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/add_interactive_git.go | 4 ++-- pkg/cli/add_interactive_orchestrator.go | 24 ++++++++++++----------- pkg/cli/add_wizard_command.go | 26 +++++++++++++++++-------- pkg/cli/audit.go | 2 +- pkg/cli/audit_diff_command.go | 2 +- pkg/cli/env_command.go | 4 ++-- pkg/cli/init_command.go | 2 +- pkg/cli/logs_command.go | 2 +- pkg/cli/project_command.go | 2 +- pkg/cli/upgrade_command.go | 2 +- 10 files changed, 41 insertions(+), 29 deletions(-) diff --git a/pkg/cli/add_interactive_git.go b/pkg/cli/add_interactive_git.go index aec29994ee9..09489c7c09d 100644 --- a/pkg/cli/add_interactive_git.go +++ b/pkg/cli/add_interactive_git.go @@ -38,13 +38,13 @@ func (c *AddInteractiveConfig) createWorkflowPRAndConfigureSecret(ctx context.Co EngineOverride: c.EngineOverride, Name: "", Force: false, - AppendText: "", + 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) diff --git a/pkg/cli/add_interactive_orchestrator.go b/pkg/cli/add_interactive_orchestrator.go index 1ab875d28a7..8383eb6ad20 100644 --- a/pkg/cli/add_interactive_orchestrator.go +++ b/pkg/cli/add_interactive_orchestrator.go @@ -18,17 +18,19 @@ 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 + 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 + AppendText string // Extra content to append to the workflow on installation + DisableSecurityScanner bool // Disable security scanning of workflow markdown content // UseCopilotRequests indicates the user chose org-billing (copilot-requests) auth // instead of a PAT when setting up the Copilot engine during the wizard. diff --git a/pkg/cli/add_wizard_command.go b/pkg/cli/add_wizard_command.go index 02bbc4ae348..741e1bca1a0 100644 --- a/pkg/cli/add_wizard_command.go +++ b/pkg/cli/add_wizard_command.go @@ -71,6 +71,8 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`, noSecret, _ := cmd.Flags().GetBool("no-secret") skipSecretLegacy, _ := cmd.Flags().GetBool("skip-secret") skipSecret := noSecret || skipSecretLegacy + appendText, _ := cmd.Flags().GetString("append") + disableSecurityScanner, _ := cmd.Flags().GetBool("no-security-scanner") addWizardLog.Printf("Starting add-wizard: workflows=%v, engine=%s, verbose=%v", workflows, engineOverride, verbose) @@ -87,14 +89,16 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`, } return RunAddInteractive(cmd.Context(), &AddInteractiveConfig{ - WorkflowSpecs: workflows, - Verbose: verbose, - EngineOverride: engineOverride, - NoGitattributes: noGitattributes, - WorkflowDir: workflowDir, - NoStopAfter: noStopAfter, - StopAfter: stopAfter, - SkipSecret: skipSecret, + WorkflowSpecs: workflows, + Verbose: verbose, + EngineOverride: engineOverride, + NoGitattributes: noGitattributes, + WorkflowDir: workflowDir, + NoStopAfter: noStopAfter, + StopAfter: stopAfter, + SkipSecret: skipSecret, + AppendText: appendText, + DisableSecurityScanner: disableSecurityScanner, }) }, } @@ -119,6 +123,12 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`, cmd.Flags().Bool("skip-secret", false, "Skip the API secret prompt (use when the secret is already set at the org or repo level)") _ = cmd.Flags().MarkHidden("skip-secret") + // Add append flag (matches --append in add command) + cmd.Flags().String("append", "", "Append extra content to the end of agentic workflow on installation") + + // Add no-security-scanner flag (matches --no-security-scanner in add command) + cmd.Flags().Bool("no-security-scanner", false, "Disable security scanning of workflow markdown content") + // Register completions RegisterEngineFlagCompletion(cmd) RegisterDirFlagCompletion(cmd, "dir") diff --git a/pkg/cli/audit.go b/pkg/cli/audit.go index 73887e88600..1df648cb1e2 100644 --- a/pkg/cli/audit.go +++ b/pkg/cli/audit.go @@ -111,7 +111,7 @@ func registerAuditCommandFlags(cmd *cobra.Command) { addRepoFlag(cmd) cmd.Flags().Bool("parse", false, "Run JavaScript parsers on agent logs and firewall logs, writing Markdown to log.md and firewall.md") cmd.Flags().String("format", "pretty", "Diff output format for multi-run mode: pretty, markdown") - cmd.Flags().StringSlice("artifacts", nil, "Artifact sets to download (default: all). Valid sets: "+strings.Join(ValidArtifactSetNames(), ", ")) + cmd.Flags().StringSlice("artifacts", nil, "Artifact sets to download (default: all, because auditing requires comprehensive artifacts for analysis). Valid sets: "+strings.Join(ValidArtifactSetNames(), ", ")) cmd.Flags().Bool("stdin", false, "Read workflow run IDs or URLs from stdin (one per line) instead of positional arguments") cmd.Flags().String("experiment", "", "Filter to runs that include this experiment name") cmd.Flags().String("variant", "", "Filter to runs with a specific variant value (requires --experiment)") diff --git a/pkg/cli/audit_diff_command.go b/pkg/cli/audit_diff_command.go index d0adb7f61a7..c68a74cf833 100644 --- a/pkg/cli/audit_diff_command.go +++ b/pkg/cli/audit_diff_command.go @@ -104,7 +104,7 @@ analyzes their data, and produces a diff showing: addJSONFlag(cmd) addRepoFlag(cmd) cmd.Flags().String("format", "pretty", "Output format: pretty, markdown") - cmd.Flags().StringSlice("artifacts", nil, "Artifact sets to download (default: all). Valid sets: "+strings.Join(ValidArtifactSetNames(), ", ")) + cmd.Flags().StringSlice("artifacts", nil, "Artifact sets to download (default: all, because auditing requires comprehensive artifacts for analysis). Valid sets: "+strings.Join(ValidArtifactSetNames(), ", ")) return cmd } diff --git a/pkg/cli/env_command.go b/pkg/cli/env_command.go index c105d8cc001..9f35c4d4ed8 100644 --- a/pkg/cli/env_command.go +++ b/pkg/cli/env_command.go @@ -137,7 +137,7 @@ func newDefaultsGetCommand() *cobra.Command { Short: "Download defaults into a YAML file", Long: `Download compiler defaults into a YAML file. -When [file] is omitted, the command writes to file.yml. +When [file] is omitted, the command writes to file.yml in the current directory. Scope resolution: - --scope defaults to repo. @@ -174,7 +174,7 @@ func newDefaultsUpdateCommand() *cobra.Command { Short: "Upload defaults from a YAML file", Long: `Upload compiler defaults from a YAML file. -When [file] is omitted, the command reads from file.yml. +When [file] is omitted, the command reads from file.yml in the current directory. Scope and flag behavior: - --scope is required (repo|org|ent). diff --git a/pkg/cli/init_command.go b/pkg/cli/init_command.go index fb7c1cdf3b9..e8eb57f5b69 100644 --- a/pkg/cli/init_command.go +++ b/pkg/cli/init_command.go @@ -68,7 +68,7 @@ After running this command, you can: ` + string(constants.CLIExtensionPrefix) + ` init --no-mcp # Skip MCP configuration ` + string(constants.CLIExtensionPrefix) + ` init --no-skill # Skip dispatcher skill creation ` + string(constants.CLIExtensionPrefix) + ` init --no-agent # Skip custom agent creation - ` + string(constants.CLIExtensionPrefix) + ` init --codespaces "" # Configure Codespaces for current repo only + ` + string(constants.CLIExtensionPrefix) + ` init --codespaces "" # Configure Codespaces for current repo only ` + string(constants.CLIExtensionPrefix) + ` init --codespaces repo1,repo2 # Codespaces with additional repos ` + string(constants.CLIExtensionPrefix) + ` init --completions # Install shell completions ` + string(constants.CLIExtensionPrefix) + ` init --create-pull-request # Initialize and create a pull request`, diff --git a/pkg/cli/logs_command.go b/pkg/cli/logs_command.go index f0d68d22963..bf0c60bfc33 100644 --- a/pkg/cli/logs_command.go +++ b/pkg/cli/logs_command.go @@ -376,7 +376,7 @@ Downloaded artifacts include (when using --artifacts all): logsCmd.Flags().String("format", "", "Output format: console (decorated tables), tsv (tab-separated), pretty (cross-run report), markdown (cross-run Markdown). Default: compact agent-optimized output") logsCmd.Flags().String("report-file", "", "Write --format markdown output directly to this file path instead of stdout (creates parent directories as needed)") logsCmd.Flags().Int("last", 0, "Alias for --count: number of recent runs to download") - logsCmd.Flags().StringSlice("artifacts", []string{"usage"}, "Artifact sets to download (default: usage). Use 'all' for everything, or comma-separate sets. Valid sets: "+validArtifactSets) + logsCmd.Flags().StringSlice("artifacts", []string{"usage"}, "Artifact sets to download (default: usage — compact summary for faster downloads). Use 'all' for everything, or comma-separate sets. Valid sets: "+validArtifactSets) logsCmd.Flags().String("cache-before", "", "(Cache eviction) Evict locally cached run folders for runs before this date, prior to downloading. Accepts deltas like -1d, -1w, -1mo (or explicit day counts like -30d), or an absolute date YYYY-MM-DD. Unlike --start-date, this only clears local cache and does not filter which runs are fetched.") logsCmd.Flags().String("after", "", "Alias for --cache-before") _ = logsCmd.Flags().MarkHidden("after") diff --git a/pkg/cli/project_command.go b/pkg/cli/project_command.go index e0db5db2928..ac048099ac1 100644 --- a/pkg/cli/project_command.go +++ b/pkg/cli/project_command.go @@ -75,7 +75,7 @@ Project Setup: - Custom fields (Tracker Id, Worker Workflow, Target Repo, Priority, Size, dates) - Enhanced Status field with "Review Required" option`, Example: ` gh aw project new "My Project" --owner @me # Create user project - gh aw project new "Team Board" --owner myorg # Create org project + gh aw project new "Team Board" --owner myorg # Create org project gh aw project new "Bugs" --owner myorg --link myorg/myrepo # Create and link to repo gh aw project new "Project Q1" --owner myorg --with-project-setup # With project setup`, Args: cobra.ExactArgs(1), diff --git a/pkg/cli/upgrade_command.go b/pkg/cli/upgrade_command.go index d31b538d4a5..5dfb6861bae 100644 --- a/pkg/cli/upgrade_command.go +++ b/pkg/cli/upgrade_command.go @@ -71,7 +71,7 @@ This command always upgrades all Markdown files in .github/workflows.`, ` + string(constants.CLIExtensionPrefix) + ` upgrade --org my-org --create-issue --yes # Auto-accept per-repo confirmations (required in CI) ` + string(constants.CLIExtensionPrefix) + ` upgrade --audit # Check dependency health without upgrading ` + string(constants.CLIExtensionPrefix) + ` upgrade --audit --json # Output audit results in JSON format - ` + string(constants.CLIExtensionPrefix) + ` upgrade --pre-releases # Include prerelease versions when self-upgrading the extension (stable releases are the default)`, + ` + string(constants.CLIExtensionPrefix) + ` upgrade --pre-releases # Include pre-release versions when upgrading the extension (stable releases are the default)`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { verbose, _ := cmd.Flags().GetBool("verbose") From b0009612ad26b501097ff88eee56463830e08c5a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Jul 2026 19:20:59 +0000 Subject: [PATCH 3/6] fix: honor wizard security scanner flag Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/cli/add_wizard_command.go | 2 ++ pkg/cli/add_wizard_command_test.go | 22 ++++++++++++++++++++++ pkg/cli/add_workflow_pr.go | 1 - 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/pkg/cli/add_wizard_command.go b/pkg/cli/add_wizard_command.go index 741e1bca1a0..9aec38766e2 100644 --- a/pkg/cli/add_wizard_command.go +++ b/pkg/cli/add_wizard_command.go @@ -53,6 +53,8 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`, ` + string(constants.CLIExtensionPrefix) + ` add-wizard https://example.com/workflow.json # Import JSON workflow definition with guided setup ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --engine copilot # Pre-select engine ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --no-secret # Skip secret prompt + ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --append "" # Append custom content + ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --no-security-scanner # Skip security scan `, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { diff --git a/pkg/cli/add_wizard_command_test.go b/pkg/cli/add_wizard_command_test.go index 1dd541724d4..54690b595f1 100644 --- a/pkg/cli/add_wizard_command_test.go +++ b/pkg/cli/add_wizard_command_test.go @@ -24,3 +24,25 @@ func TestAddWizardCommand_UsesStandardThreePartWorkflowSpecWording(t *testing.T) assert.Contains(t, cmd.Long, "For github/*, githubnext/*, and microsoft/* sources, shorthand resolves on github.com.") assert.Contains(t, cmd.Long, "Use full https://github.com/... source URLs for other public github.com workflows.") } + +func TestAddWizardCommand_FlagUsageMatchesAddCommand(t *testing.T) { + addCmd := NewAddCommand(validateEngineStub) + wizardCmd := NewAddWizardCommand(validateEngineStub) + + for _, flagName := range []string{"append", "no-security-scanner"} { + addFlag := addCmd.Flags().Lookup(flagName) + wizardFlag := wizardCmd.Flags().Lookup(flagName) + + require.NotNil(t, addFlag, "add should define %q", flagName) + require.NotNil(t, wizardFlag, "add-wizard should define %q", flagName) + assert.Equal(t, addFlag.Usage, wizardFlag.Usage, "%q usage should stay in sync between add and add-wizard", flagName) + } +} + +func TestAddWizardCommand_ExamplesMentionNewFlags(t *testing.T) { + cmd := NewAddWizardCommand(func(string) error { return nil }) + require.NotNil(t, cmd) + + assert.Contains(t, cmd.Example, "--append \"\"", "add-wizard examples should show append usage") + assert.Contains(t, cmd.Example, "--no-security-scanner", "add-wizard examples should show no-security-scanner usage") +} diff --git a/pkg/cli/add_workflow_pr.go b/pkg/cli/add_workflow_pr.go index 5d9c3851a52..f1ae86afa01 100644 --- a/pkg/cli/add_workflow_pr.go +++ b/pkg/cli/add_workflow_pr.go @@ -87,7 +87,6 @@ func addWorkflowsWithPR(ctx context.Context, workflows []*ResolvedWorkflow, opts // Add workflows using the resolved workflow path addWorkflowPRLog.Print("Adding workflows to repository") prOpts := opts - prOpts.DisableSecurityScanner = false if err := addWorkflowsWithTracking(ctx, workflows, tracker, prOpts); err != nil { addWorkflowPRLog.Printf("Failed to add workflows: %v", err) // Rollback on error From 5f8f51a070221ace04f2c71e54569134e700a8c1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Jul 2026 19:31:22 +0000 Subject: [PATCH 4/6] test: keep add-wizard examples parser-safe Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/cli/add_wizard_command.go | 2 +- pkg/cli/add_wizard_command_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cli/add_wizard_command.go b/pkg/cli/add_wizard_command.go index 9aec38766e2..b81898154fd 100644 --- a/pkg/cli/add_wizard_command.go +++ b/pkg/cli/add_wizard_command.go @@ -53,7 +53,7 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`, ` + string(constants.CLIExtensionPrefix) + ` add-wizard https://example.com/workflow.json # Import JSON workflow definition with guided setup ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --engine copilot # Pre-select engine ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --no-secret # Skip secret prompt - ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --append "" # Append custom content + ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --append "custom footer" # Append custom content ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --no-security-scanner # Skip security scan `, Args: func(cmd *cobra.Command, args []string) error { diff --git a/pkg/cli/add_wizard_command_test.go b/pkg/cli/add_wizard_command_test.go index 54690b595f1..fb32a64ee49 100644 --- a/pkg/cli/add_wizard_command_test.go +++ b/pkg/cli/add_wizard_command_test.go @@ -43,6 +43,6 @@ func TestAddWizardCommand_ExamplesMentionNewFlags(t *testing.T) { cmd := NewAddWizardCommand(func(string) error { return nil }) require.NotNil(t, cmd) - assert.Contains(t, cmd.Example, "--append \"\"", "add-wizard examples should show append usage") + assert.Contains(t, cmd.Example, "--append \"custom footer\"", "add-wizard examples should show append usage") assert.Contains(t, cmd.Example, "--no-security-scanner", "add-wizard examples should show no-security-scanner usage") } From 8d623beb9710c3c501d8ec3af3f80464e8153623 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Jul 2026 02:34:46 +0000 Subject: [PATCH 5/6] test: decouple MCP integration session timeout from connect timeout Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/mcp_server_json_integration_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/cli/mcp_server_json_integration_test.go b/pkg/cli/mcp_server_json_integration_test.go index 07c4ce71950..61e5640a2ca 100644 --- a/pkg/cli/mcp_server_json_integration_test.go +++ b/pkg/cli/mcp_server_json_integration_test.go @@ -85,14 +85,16 @@ This is a test workflow. serverCmd.Dir = tmpDir transport := &mcp.CommandTransport{Command: serverCmd} - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + connectCtx, connectCancel := context.WithTimeout(context.Background(), 30*time.Second) + defer connectCancel() - session, err := client.Connect(ctx, transport, nil) + session, err := client.Connect(connectCtx, transport, nil) if err != nil { - cancel() t.Fatalf("Failed to connect to MCP server: %v", err) } + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + return session, originalDir, ctx, cancel } From 0e6366020d1330414b01b506bb7ffc1e6a3857f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Jul 2026 02:37:41 +0000 Subject: [PATCH 6/6] test: clean up MCP connect timeout handling Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/mcp_server_json_integration_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/cli/mcp_server_json_integration_test.go b/pkg/cli/mcp_server_json_integration_test.go index 61e5640a2ca..3955e7f6989 100644 --- a/pkg/cli/mcp_server_json_integration_test.go +++ b/pkg/cli/mcp_server_json_integration_test.go @@ -86,9 +86,8 @@ This is a test workflow. transport := &mcp.CommandTransport{Command: serverCmd} connectCtx, connectCancel := context.WithTimeout(context.Background(), 30*time.Second) - defer connectCancel() - session, err := client.Connect(connectCtx, transport, nil) + connectCancel() if err != nil { t.Fatalf("Failed to connect to MCP server: %v", err) }