Skip to content
Merged
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
5 changes: 0 additions & 5 deletions .github/workflows/integration-agentics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@ jobs:
./gh-aw add githubnext/agentics/issue-triage
echo "Successfully installed agentics workflows"

- name: List installed workflows
run: |
echo "Listing installed workflows..."
./gh-aw list

- name: Test MCP server discovery
run: |
echo "Testing MCP server discovery..."
Expand Down
1 change: 0 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ make agent-finish # Complete validation
```bash
./gh-aw --help
./gh-aw compile
./gh-aw list
./gh-aw mcp list # MCP server management
./gh-aw logs # Download and analyze workflow logs
./gh-aw audit 123456 # Audit a specific workflow run
Expand Down
16 changes: 2 additions & 14 deletions cmd/gh-aw/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,6 @@ The workflow file is then executed by GitHub Actions in response to events in th
},
}

var listCmd = &cobra.Command{
Use: "list",
Short: "List available engines and other information",
Run: func(cmd *cobra.Command, args []string) {
if err := cli.ListEnginesAndOtherInformation(verbose); err != nil {
fmt.Fprintln(os.Stderr, console.FormatErrorMessage(err.Error()))
os.Exit(1)
}
},
}

var newCmd = &cobra.Command{
Use: "new <workflow-base-name>",
Short: "Create a new workflow markdown file with example configuration",
Expand Down Expand Up @@ -222,8 +211,8 @@ var versionCmd = &cobra.Command{
Use: "version",
Short: "Show version information",
Run: func(cmd *cobra.Command, args []string) {
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("%s version %s", constants.CLIExtensionPrefix, version)))
fmt.Fprintln(os.Stderr, console.FormatInfoMessage("GitHub Agentic Workflows CLI from GitHub Next"))
fmt.Println(console.FormatInfoMessage(fmt.Sprintf("%s version %s", constants.CLIExtensionPrefix, version)))
fmt.Println(console.FormatInfoMessage("GitHub Agentic Workflows CLI from GitHub Next"))
},
}

Expand Down Expand Up @@ -283,7 +272,6 @@ func init() {
// Add all commands to root
rootCmd.AddCommand(addCmd)
rootCmd.AddCommand(trialCmd)
rootCmd.AddCommand(listCmd)
rootCmd.AddCommand(newCmd)
rootCmd.AddCommand(initCmd)

Expand Down
21 changes: 4 additions & 17 deletions cmd/gh-aw/main_entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,19 +147,6 @@ func TestMainFunction(t *testing.T) {
}
})

t.Run("list command is available", func(t *testing.T) {
found := false
for _, cmd := range rootCmd.Commands() {
if cmd.Name() == "list" {
found = true
break
}
}
if !found {
t.Error("list command should be available")
}
})

t.Run("root command help", func(t *testing.T) {
// Capture output
oldStderr := os.Stderr
Expand Down Expand Up @@ -282,7 +269,7 @@ func TestMainFunctionExecutionPath(t *testing.T) {

t.Run("main function basic execution flow", func(t *testing.T) {
// Test that main function sets up CLI properly and exits cleanly for valid commands
cmd := exec.Command("go", "run", ".", "list")
cmd := exec.Command("go", "run", ".", "version")
cmd.Dir = "."

// This should run successfully (exit code 0) even if no workflows found
Expand All @@ -293,13 +280,13 @@ func TestMainFunctionExecutionPath(t *testing.T) {
// Some commands might return non-zero but still function properly
t.Logf("Command returned exit code %d, output: %s", exitError.ExitCode(), string(output))
} else {
t.Fatalf("Failed to run main with list command: %v", err)
t.Fatalf("Failed to run main with version command: %v", err)
}
}

// Should produce some output
if len(output) == 0 {
t.Error("list command should produce some output")
t.Error("version command should produce some output")
}
})
}
Expand Down Expand Up @@ -365,7 +352,7 @@ func TestCommandLineIntegration(t *testing.T) {

t.Run("command structure validation", func(t *testing.T) {
// Test that essential commands are present
expectedCommands := []string{"add", "compile", "list", "remove", "status", "run", "version", "mcp"}
expectedCommands := []string{"add", "compile", "remove", "status", "run", "version", "mcp"}

cmdMap := make(map[string]bool)
for _, cmd := range rootCmd.Commands() {
Expand Down
26 changes: 18 additions & 8 deletions pkg/cli/add_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,19 +280,22 @@ func addWorkflowsWithPR(workflows []*WorkflowSpec, number int, verbose bool, eng
// Commit changes
var commitMessage, prTitle, prBody, joinedNames string
if len(workflows) == 1 {
joinedNames = workflows[0].WorkflowPath
joinedNames = workflows[0].WorkflowName
commitMessage = fmt.Sprintf("Add agentic workflow %s", joinedNames)
prTitle = fmt.Sprintf("Add agentic workflow %s", joinedNames)
prBody = fmt.Sprintf("Add agentic workflow %s", joinedNames)
} else {
// Get workflow.Workflo
workflowNames := make([]string, len(workflows))
for i, wf := range workflows {
workflowNames[i] = wf.WorkflowPath
workflowNames[i] = wf.WorkflowName
}
joinedNames = strings.Join(workflowNames, ", ")
commitMessage = fmt.Sprintf("Add agentic workflows: %s", joinedNames)
prTitle = fmt.Sprintf("Add agentic workflows: %s", joinedNames)
prBody = fmt.Sprintf("Add agentic workflows: %s", joinedNames)
}

commitMessage = fmt.Sprintf("Add workflows: %s", joinedNames)
prTitle = fmt.Sprintf("Add workflows: %s", joinedNames)
prBody = fmt.Sprintf("Automatically created PR to add workflows: %s", joinedNames)
if err := commitChanges(commitMessage, verbose); err != nil {
if rollbackErr := tracker.RollbackAllFiles(verbose); rollbackErr != nil && verbose {
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("Failed to rollback files: %v", rollbackErr)))
Expand Down Expand Up @@ -324,7 +327,7 @@ func addWorkflowsWithPR(workflows []*WorkflowSpec, number int, verbose bool, eng
}

if len(workflows) == 1 {
fmt.Printf("Successfully created PR for workflow: %s\n", workflows[0])
fmt.Printf("Successfully created PR for workflow: %s\n", workflows[0].WorkflowName)
} else {
fmt.Printf("Successfully created PR for workflows: %s\n", joinedNames)
}
Expand Down Expand Up @@ -361,8 +364,15 @@ func addWorkflowWithTracking(workflow *WorkflowSpec, number int, verbose bool, e
if err != nil {
fmt.Fprintln(os.Stderr, console.FormatErrorMessage(fmt.Sprintf("Workflow '%s' not found.", workflowPath)))

// Show available workflows using the same logic as ListEnginesAndOtherInformation
fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Run '"+constants.CLIExtensionPrefix+" list' to see available workflows."))
// Provide information about workflow repositories
fmt.Println("\nTo add workflows to your project:")
fmt.Println("=================================")
fmt.Println("Use the 'add' command with repository/workflow specifications:")
fmt.Println(" " + constants.CLIExtensionPrefix + " add owner/repo/workflow-name")
fmt.Println(" " + constants.CLIExtensionPrefix + " add owner/repo/workflow-name@version")
fmt.Println("\nExample:")
fmt.Println(" " + constants.CLIExtensionPrefix + " add githubnext/agentics/ci-doctor")
fmt.Println(" " + constants.CLIExtensionPrefix + " add githubnext/agentics/daily-plan@main")

return fmt.Errorf("workflow not found: %s", workflowPath)
}
Expand Down
21 changes: 0 additions & 21 deletions pkg/cli/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,6 @@ import (

// Test the CLI functions that are exported from this package

func TestListWorkflows(t *testing.T) {
// Test the ListEnginesAndOtherInformation function (which includes listAgenticEngines)
err := ListEnginesAndOtherInformation(false)

// Should return nil (no error) and print table-formatted output
if err != nil {
t.Errorf("ListEnginesAndOtherInformation should not return an error for valid input, got: %v", err)
}
}

func TestListWorkflowsVerbose(t *testing.T) {
// Test the ListEnginesAndOtherInformation function in verbose mode
err := ListEnginesAndOtherInformation(true)

// Should return nil (no error) and print table-formatted output with descriptions
if err != nil {
t.Errorf("ListEnginesAndOtherInformation verbose mode should not return an error for valid input, got: %v", err)
}
}

func TestCompileWorkflows(t *testing.T) {
// Clean up any existing .github/workflows for this test
defer os.RemoveAll(".github")
Expand Down Expand Up @@ -401,7 +381,6 @@ func TestAllCommandsExist(t *testing.T) {
expectError bool
name string
}{
{func() error { return ListEnginesAndOtherInformation(false) }, false, "ListEnginesAndOtherInformation"},
{func() error {
config := CompileConfig{
MarkdownFiles: []string{},
Expand Down
121 changes: 0 additions & 121 deletions pkg/cli/list_command.go
Original file line number Diff line number Diff line change
@@ -1,122 +1 @@
package cli

import (
"fmt"
"os"

"github.com/githubnext/gh-aw/pkg/console"
"github.com/githubnext/gh-aw/pkg/constants"
"github.com/githubnext/gh-aw/pkg/workflow"
)

// GitHubWorkflow represents a GitHub Actions workflow from the API
// GitHubWorkflowsResponse represents the GitHub API response for workflows
// Note: The API returns an array directly, not wrapped in a workflows field

// ListEnginesAndOtherInformation lists available workflow components
func ListEnginesAndOtherInformation(verbose bool) error {
if verbose {
fmt.Fprintln(os.Stderr, console.FormatProgressMessage("Searching for available workflow components..."))
}

// List available agentic engines
if err := listAgenticEngines(verbose); err != nil {
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("Failed to list agentic engines: %v", err)))
}

// Provide information about workflow repositories
fmt.Println("\nTo add workflows to your project:")
fmt.Println("=================================")
fmt.Println("Use the 'add' command with repository/workflow specifications:")
fmt.Println(" " + constants.CLIExtensionPrefix + " add owner/repo/workflow-name")
fmt.Println(" " + constants.CLIExtensionPrefix + " add owner/repo/workflow-name@version")
fmt.Println("\nExample:")
fmt.Println(" " + constants.CLIExtensionPrefix + " add githubnext/agentics/ci-doctor")
fmt.Println(" " + constants.CLIExtensionPrefix + " add githubnext/agentics/daily-plan@main")
return nil
}

// listAgenticEngines lists all available agentic engines with their characteristics
func listAgenticEngines(verbose bool) error {
// Create an engine registry directly to access the engines
registry := workflow.GetGlobalEngineRegistry()

// Get all supported engines from the registry
engines := registry.GetSupportedEngines()

if len(engines) == 0 {
fmt.Fprintln(os.Stderr, console.FormatInfoMessage("No agentic engines available."))
return nil
}

// Build table configuration
var headers []string
if verbose {
headers = []string{"ID", "Display Name", "Status", "MCP", "HTTP Transport", "Description"}
} else {
headers = []string{"ID", "Display Name", "Status", "MCP", "HTTP Transport"}
}

var rows [][]string

for _, engineID := range engines {
engine, err := registry.GetEngine(engineID)
if err != nil {
if verbose {
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("Failed to get engine '%s': %v", engineID, err)))
}
continue
}

// Determine status
status := "Stable"
if engine.IsExperimental() {
status = "Experimental"
}

// MCP support
mcpSupport := "No"
if engine.SupportsToolsAllowlist() {
mcpSupport = "Yes"
}

// HTTP transport support
httpTransport := "No"
if engine.SupportsHTTPTransport() {
httpTransport = "Yes"
}

// Build row data
var row []string
if verbose {
row = []string{
engine.GetID(),
engine.GetDisplayName(),
status,
mcpSupport,
httpTransport,
engine.GetDescription(),
}
} else {
row = []string{
engine.GetID(),
engine.GetDisplayName(),
status,
mcpSupport,
httpTransport,
}
}
rows = append(rows, row)
}

// Render the table
tableConfig := console.TableConfig{
Title: "Available Agentic Engines",
Headers: headers,
Rows: rows,
}
fmt.Fprint(os.Stderr, console.RenderTable(tableConfig))

fmt.Fprintln(os.Stderr, "")
return nil
}
3 changes: 2 additions & 1 deletion pkg/cli/trial_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ func RunWorkflowTrials(workflowSpecs []string, targetRepoSlug string, trialRepo
for i, spec := range parsedSpecs {
workflowNames[i] = spec.WorkflowName
}
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Starting trial of %d workflows (%s)", len(parsedSpecs), strings.Join(workflowNames, ", "))))
joinedNames := strings.Join(workflowNames, ", ")
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Starting trial of %d workflows (%s)", len(parsedSpecs), joinedNames)))
}

// Generate a unique datetime-ID for this trial session
Expand Down