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
6 changes: 0 additions & 6 deletions docs/src/content/docs/blog/2026-01-21-twelve-lessons.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,6 @@ As workflows start using multiple MCP servers, having agents that can validate a

Early on, we'd see agents fail with vague errors like "connection refused." The MCP Inspector proactively checks all MCP server configurations, validates network access, and generates status reports. This visibility transformed debugging from hours of detective work into reading a dashboard.

### Dispatcher Patterns Scale Command Complexity

Instead of one monolithic agent handling all requests, dispatcher agents could route to specialized sub-agents or commands. This made the system more maintainable and allowed for progressive feature addition.

The [Workflow Generator](https://github.com/githubnext/gh-aw/tree/2c1f68a721ae7b3b67d0c2d93decf1fa5bcf7ee3/.github/workflows/workflow-generator.md) and [Campaign Generator](https://github.com/githubnext/gh-aw/tree/2c1f68a721ae7b3b67d0c2d93decf1fa5bcf7ee3/.github/workflows/campaign-generator.md) demonstrated this pattern well. Rather than cramming all generation logic into one massive prompt, they identified user intent and dispatched to specialized generation workflows. This kept individual agents focused and made the system easier to extend.

### Task Queuing Is Everywhere

The task queue pattern provided a simple way to queue and distribute work across multiple workflow runs. Breaking large projects into discrete tasks allowed incremental progress with clear state tracking, recording tasks as issues, discussions, or project cards.
Expand Down
7 changes: 3 additions & 4 deletions docs/src/content/docs/blog/2026-01-24-design-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ Use these when:

- Large refactoring projects
- Test coverage improvements
- Performance optimization campaigns
- Performance optimization
- Backlog reduction initiatives
- Quality improvement programs

Expand Down Expand Up @@ -314,19 +314,18 @@ Some key characteristics are:

**Orchestrate multi-step workflows via state machines**

These agentic workflows coordinate complex workflows through campaigns or task queue patterns. Track state across runs (open/in-progress/completed).
These agentic workflows coordinate complex workflows through task queue patterns. Track state across runs (open/in-progress/completed).

Use these when:

- Campaign management
- Task management
- Multi-step coordination
- Workflow generation
- Development monitoring
- Task distribution

Here are some examples:

- [`campaign-generator`](https://github.com/githubnext/gh-aw/tree/2c1f68a721ae7b3b67d0c2d93decf1fa5bcf7ee3/.github/workflows/campaign-generator.md) - Creates and coordinates campaigns
- [`workflow-generator`](https://github.com/githubnext/gh-aw/tree/2c1f68a721ae7b3b67d0c2d93decf1fa5bcf7ee3/.github/workflows/workflow-generator.md) - Generates new workflows
- [`dev-hawk`](https://github.com/githubnext/gh-aw/tree/2c1f68a721ae7b3b67d0c2d93decf1fa5bcf7ee3/.github/workflows/dev-hawk.md) - Development monitoring

Expand Down
12 changes: 6 additions & 6 deletions pkg/cli/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,16 +291,16 @@ func addCampaignGeneratorWorkflow(verbose bool) error {
return fmt.Errorf("failed to find git root: %w", err)
}

// Determine the workflows directory
workflowsDir := filepath.Join(gitRoot, ".github", "workflows")
if err := os.MkdirAll(workflowsDir, 0755); err != nil {
initLog.Printf("Failed to create workflows directory: %v", err)
return fmt.Errorf("failed to create workflows directory: %w", err)
// Determine the aw directory (for core workflows)
awDir := filepath.Join(gitRoot, ".github", "aw")
if err := os.MkdirAll(awDir, 0755); err != nil {
initLog.Printf("Failed to create aw directory: %v", err)
return fmt.Errorf("failed to create aw directory: %w", err)
}

// Build the campaign-generator workflow
data := campaign.BuildCampaignGenerator()
workflowPath := filepath.Join(workflowsDir, "campaign-generator.md")
workflowPath := filepath.Join(awDir, "campaign-generator.md")

// Render the workflow to markdown
content := renderCampaignGeneratorMarkdown(data)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/init_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ With --codespaces flag:

With --campaign flag:
- Creates .github/agents/agentic-campaigns.agent.md with the Campaigns dispatcher agent
- Adds campaign-generator.md workflow to .github/workflows/ for creating campaigns from issues
- Adds campaign-generator.md workflow to .github/aw/ for creating campaigns from issues
- Enables campaign-related prompts and functionality for multi-workflow coordination

With --completions flag:
Expand Down
4 changes: 2 additions & 2 deletions pkg/cli/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,13 @@ func TestInitRepository_Campaign(t *testing.T) {
}

// Verify campaign-generator workflow was generated (not added from repo)
campaignWorkflowPath := filepath.Join(tempDir, ".github", "workflows", "campaign-generator.md")
campaignWorkflowPath := filepath.Join(tempDir, ".github", "aw", "campaign-generator.md")
if _, err := os.Stat(campaignWorkflowPath); os.IsNotExist(err) {
t.Errorf("Expected campaign-generator workflow to exist at %s", campaignWorkflowPath)
}

// Verify campaign-generator lock file was created
campaignLockPath := filepath.Join(tempDir, ".github", "workflows", "campaign-generator.lock.yml")
campaignLockPath := filepath.Join(tempDir, ".github", "aw", "campaign-generator.lock.yml")
if _, err := os.Stat(campaignLockPath); os.IsNotExist(err) {
t.Errorf("Expected campaign-generator lock file to exist at %s", campaignLockPath)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/workflow/campaign_trigger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestCampaignGeneratorWorkflow(t *testing.T) {
compiler := NewCompiler(false, "", "test")

// Test compilation of the actual campaign-generator workflow
workflowPath := "../../.github/workflows/campaign-generator.md"
workflowPath := "../../.github/aw/campaign-generator.md"

// Check if file exists
if _, err := os.Stat(workflowPath); os.IsNotExist(err) {
Expand Down
Loading
Loading