Command Implementation
Overview
Commands implement the business logic for CLI operations. Each command follows a consistent pattern: load configuration, validate settings, execute operations (often in parallel), and report results. Commands are thin wrappers that orchestrate interactions between storage, GitHub client, and agents.
Architecture
Command Pattern
All commands located in src/gh_worker/commands/ follow a standard structure:
Entry Point:
{command}_command()- Main function called by CLI- Accepts command-specific parameters
- Takes optional
config_pathparameter
Helper Functions:
{operation}_repository()- Per-repository operation{operation}_issue()- Per-issue operation
Common Flow:
- Load configuration
- Validate required settings
- Initialize clients and stores
- Resolve repository/issue scope
- Execute operations (parallel if configured)
- Report results
Available Commands
Commands are ordered in help as: init, repositories, issues, monitor, work, config.
init
Initializes configuration interactively.
Location: src/gh_worker/commands/init.py
Operations:
- Interactive configuration setup
- Prompts for required settings (issues-path, repository-path)
- Validates paths and creates directories
- Generates initial config file at
~/.config/gh-worker/config.yaml - Sets sensible defaults for parallelism and agent configuration
Example:
Flow:
- Check if config already exists and prompt for overwrite
- Prompt for issues-path with validation
- Prompt for repository-path with validation
- Create directories if they don't exist
- Set default configuration values
- Save configuration to YAML file
- Display success message with config location
config
Manages application configuration.
Location: src/gh_worker/commands/config.py
Operations:
- List all configuration values (
--list) - Get configuration value
- Set configuration value
- Uses dotted key paths
Example:
# List all configuration values
gh-worker config --list
# Get value
gh-worker config issues-path
# Set value
gh-worker config issues-path /var/gh-worker/issues
gh-worker config plan.parallelism 3
repositories add
Adds repositories to track.
Location: src/gh_worker/commands/add.py
Operations:
- Parse repository names
- Validate repository access
- Initialize storage structure
- Create repository metadata
- Optionally clone to repository-path when
--cloneis passed
Example:
gh-worker repositories add octocat/hello-world
gh-worker repositories add octocat/hello-world --clone
list
Lists all repositories under management.
Location: src/gh_worker/commands/list.py
Operations:
- Load configuration and validate issues_path
- Use IssueStore.list_repositories() to discover tracked repos
- Display repository names (owner/repo format)
Example:
remove
Removes repositories from tracking.
Location: src/gh_worker/commands/remove.py
Operations:
- Parse repository names
- Remove repository directory from issues_path (issues, plans, metadata)
- By default keeps cloned repository in repository_path (use --no-keep-clone to remove it)
Example:
gh-worker repositories remove octocat/hello-world
gh-worker repositories remove octocat/hello-world --no-keep-clone
issues list
Lists synced issues with plan and implementation status.
Location: src/gh_worker/commands/issues_list.py
Operations:
- Load issues from IssueStore and PlanStore
- Display table with issue number, title, author, assignees, plan status, implementation status
- Support filters: repo, all_repos, title, author, assignee, plan, implementation
Example:
gh-worker issues list --repo octocat/hello-world
gh-worker issues list --all-repos --plan approved --implementation none
Flow:
- Load configuration and validate issues_path
- Initialize IssueStore and PlanStore
- Resolve repositories (specific or all)
- For each repository, load issues and plan metadata
- Apply filters (title, author, assignee, plan status, implementation status)
- Display results in rich table format
issues sync
Synchronizes issues from GitHub to local storage.
Location: src/gh_worker/commands/sync.py
Operations:
- Fetch issues from GitHub (all or specific)
- Convert from GitHub JSON to Issue model
- Save to IssueStore
- Update repository timestamps for incremental sync
- Support filters: since, issue_numbers, search, assignee
- Support force refresh (--force) to re-fetch and update description.md
Helper Function:
sync_repository()- Sync single repository
Flow:
- Load configuration and validate issues_path
- Initialize GHClient and IssueStore
- Resolve repositories (specific, all, or from storage)
- For each repository:
- Get since timestamp (from parameter or last sync)
- Fetch issues (specific numbers or all matching filters)
- Save each issue to storage
- Track latest update timestamp
- Update repository timestamp
- Report total issues synced
issues plan
Generates implementation plans using LLM agents.
Location: src/gh_worker/commands/plan.py
Operations:
- Find issues without plans
- Use agent to generate plans
- Save plans with metadata
- Support parallel execution
Helper Functions:
plan_issue()- Generate plan for single issueplan_command()- Sync wrapperplan_command_async()- Async implementation
Flow:
- Load configuration and validate paths
- Initialize agent, GHClient, IssueStore, PlanStore
- Clone repositories
- Resolve issues (specific numbers or all without plans)
- Create ParallelExecutor with configured parallelism
- For each issue in parallel:
- Read issue content
- Call agent.plan()
- Save plan content and metadata
- Log results
- Report success/failure counts
plans review
Creates a worktree with the plan symlinked for editing.
Location: src/gh_worker/commands/review.py
Operations:
- Create worktree with plan symlinked for review/editing
- Only applies to plans with status PENDING and an existing plan file
Example:
Flow:
- Load configuration and validate issues_path
- Initialize IssueStore and PlanStore
- Find plan with status PENDING and existing plan file
- Create worktree, symlink plan file for editing
issues review
Reviews code implementations using LLM agents.
Location: src/gh_worker/commands/review_issues.py
Operations:
- Find implementations with COMPLETED status and branch name
- Fetch PR information from GitHub (branch name, description)
- Use agent to review code against plan/issue
- Write review outcome to review.md in issue directory
- Update plan metadata with review status
CLI Flags:
--parallelism- Number of parallel reviews (default: from config)--force- Review even if already reviewed--assignee- Filter by assignee (use @me for current user)--agent- Override agent to use (e.g., "cursor-agent", "mock")
Example:
gh-worker issues review --repo octocat/hello-world
gh-worker issues review --repo octocat/hello-world --issue-numbers 42
gh-worker issues review --repo octocat/hello-world --parallelism 2
Flow:
- Load configuration and validate issues_path
- Initialize IssueStore, PlanStore, GHClient
- Resolve repositories and find implementations waiting review
- For each implementation:
- Fetch PR info from GitHub (branch name, description)
- Clone repository if not exists
- Create worktree for PR branch
- Load issue content and plan (if available)
- Call agent.review() (streaming)
- Capture completion content
- Write review to review.md
- Update metadata with review status
- Report success/failure counts
Note: A plan does not need to exist for review. If no plan is available, the review uses the PR description from GitHub.
issues implement
Executes plans and creates pull requests with git worktree support.
Location: src/gh_worker/commands/implement.py
Operations:
- Find issues with completed plans
- Use agent to implement plans
- Create branches using git worktree for isolation (configurable)
- Optionally push branches to remote
- Optionally create pull requests
- Update plan metadata with results
- Support parallel execution with streaming
- Clean up worktrees after completion (configurable)
CLI Flags:
--use-worktree- Use git worktree for isolated implementation (overrides config, default: True)--push-branch- Push branch to remote after implementation (overrides config, default: False)--create-pr- Create pull request after implementation (overrides config, default: False)--delete-worktree- Delete worktree after implementation (overrides config, default: True)--agent- Override agent to use (e.g., "cursor-agent", "mock")
Helper Functions:
implement_issue()- Implement single issue with worktree managementimplement_command()- Sync wrapperimplement_command_async()- Async implementation
Flow:
- Load configuration and validate paths
- Initialize agent (with optional override), GHClient, IssueStore, PlanStore
- Validate agent environment
- Resolve issues with plans (specific numbers or all pending)
- Create ParallelExecutor with configured parallelism
- For each issue in parallel:
- Load issue and plan
- Update metadata status to IN_PROGRESS
- Create git worktree if enabled (isolated workspace)
- Call agent.implement() (streaming)
- Stream events to console
- Optionally commit changes using agent.commit()
- Optionally push branch to remote
- Optionally create PR using gh CLI
- Update metadata with results (branch, PR URL, status)
- Clean up worktree if enabled
- Log completion
- Report success/failure counts
monitor
Monitors ongoing agent sessions (plan or implementation).
Location: src/gh_worker/commands/monitor.py
Operations:
- Retrieve session ID from plan metadata
- Connect to agent session
- Stream session events
- Display progress
- Supports
--agentoverride
Flow:
- Load configuration
- Initialize agent (with optional override) and PlanStore
- Load plan metadata for issue
- Extract session ID (required; typically set during implementation)
- Call agent.monitor() (streaming)
- Display events to console
work
Orchestrates complete sync → plan → implement workflow.
Location: src/gh_worker/commands/work.py
Operations:
- Create WorkOrchestrator
- Run single cycle or continuous mode
- Handle errors and continue
Flow:
- Create WorkOrchestrator with parameters
- If once mode: await orchestrator.run_once()
- If continuous: await orchestrator.run_continuous(frequency)
- Orchestrator handles sync → plan → implement phases
Common Patterns
Configuration Loading
config = ConfigManager(config_path)
app_config = config.load()
if not app_config.issues_path:
print("Error: issues-path not configured.")
return
Repository Resolution
if repo:
repositories = [Repository.from_string(repo)]
elif all_repos:
repositories = issue_store.list_repositories()
else:
print("Error: Specify --repo or --all-repos")
return
Parallel Execution
executor = ParallelExecutor(
max_workers=parallelism or app_config.plan.parallelism
)
results = await executor.execute(
items=issues,
task_func=plan_issue,
task_name="plan_issues"
)
Error Handling
try:
result = gh_client.get_issue(repository, issue_number)
except Exception as e:
logger.error("operation_failed", error=str(e))
print(f"Error: {e}")
Result Reporting
success_count = sum(1 for r in results if r.success)
failure_count = len(results) - success_count
print(f"Completed: {success_count} succeeded, {failure_count} failed")
Requirements
Command Structure
MUST:
- Accept optional config_path parameter
- Load and validate configuration
- Initialize required clients and stores
- Handle missing configuration gracefully
- Report results to stdout
- Log operations with structured logging
- Return or exit with appropriate status
SHOULD:
- Validate input parameters
- Provide helpful error messages
- Support both specific and bulk operations
- Use parallel execution for multiple items
- Track and report success/failure counts
- Log start and completion
MAY:
- Support dry-run mode
- Provide progress indicators
- Support resume/retry for failed items
- Cache or reuse resources
Configuration Integration
MUST:
- Load configuration via ConfigManager
- Validate required settings (paths, etc.)
- Use configuration defaults
- Allow parameter overrides
- Handle missing configuration file
SHOULD:
- Print helpful messages for missing config
- Show configuration commands in errors
- Log configuration values used
- Support custom config paths
MAY:
- Validate configuration before execution
- Support environment variable overrides
- Provide configuration recommendations
Repository and Issue Scope
MUST:
- Support specific repository via parameter
- Support all repositories via flag
- Support specific issue numbers
- Resolve repositories from storage
- Validate repository format
SHOULD:
- Handle repository not found gracefully
- Skip missing issues with warning
- Support empty repository lists
- Log repository and issue counts
MAY:
- Support repository patterns
- Implement issue filters (labels, state)
- Provide issue discovery
- Support repository aliases
Parallel Execution
MUST:
- Use ParallelExecutor for multi-item operations
- Support configurable parallelism
- Default to configuration value
- Allow parameter override
- Handle per-item errors without stopping
SHOULD:
- Log parallelism settings
- Report per-item results
- Aggregate success/failure counts
- Stream output for long operations
MAY:
- Support adaptive parallelism
- Implement rate limiting
- Provide progress tracking
- Support cancellation
Error Handling
MUST:
- Catch and log exceptions
- Continue processing other items on error
- Report errors to user
- Use appropriate log levels
- Preserve error context
SHOULD:
- Classify errors by severity
- Provide actionable error messages
- Include troubleshooting hints
- Log full tracebacks for debugging
MAY:
- Implement retry logic
- Support error recovery
- Aggregate error reports
- Provide error statistics
Output and Logging
MUST:
- Print summary results
- Log all operations with structured fields
- Write errors to stderr
- Write results to stdout
- Use consistent formatting
SHOULD:
- Provide progress updates for long operations
- Show item counts (total, processed, failed)
- Use clear, concise messages
- Include timestamps in logs
MAY:
- Support JSON output format
- Provide verbose mode
- Support colored output
- Stream real-time progress
Usage Examples
Sync Command
def sync_command(repo, all_repos, since, issue_numbers, search, config_path):
# Load configuration
config = ConfigManager(config_path)
app_config = config.load()
# Validate
if not app_config.issues_path:
print("Error: issues-path not configured")
return
# Initialize
gh_client = GHClient()
issue_store = IssueStore(app_config.issues_path)
# Resolve repositories
if repo:
repositories = [Repository.from_string(repo)]
elif all_repos:
repositories = issue_store.list_repositories()
else:
print("Error: Specify --repo or --all-repos")
return
# Sync each repository
total = 0
for repository in repositories:
count = sync_repository(
repository, issue_store, gh_client,
since, issue_numbers, search
)
total += count
print(f"Synced {total} issues across {len(repositories)} repositories")
Plan Command (Async)
async def plan_command_async(repo, issue_numbers, parallelism, config_path):
# Load configuration and initialize
config = ConfigManager(config_path)
app_config = config.load()
agent = get_agent(app_config)
plan_store = PlanStore(app_config.issues_path)
# Clone repository
gh_client = GHClient(app_config.repository_path)
repository = Repository.from_string(repo)
repo_path = gh_client.clone_repo(repository)
# Find issues without plans
issues = [
num for num in issue_numbers
if not plan_store.has_plan(repository, num)
]
# Plan in parallel
executor = ParallelExecutor(
max_workers=parallelism or app_config.plan.parallelism
)
async def plan_issue(issue_num):
# Generate and save plan
result = await agent.plan(issue_content, repo_path, issue_num)
plan_store.create_plan(repository, issue_num, result.output)
return result
results = await executor.execute(issues, plan_issue, "plan")
# Report
success = sum(1 for r in results if r.success)
print(f"Generated {success}/{len(results)} plans")
Extension Points
Commands can be extended to support:
- Additional GitHub operations (releases, workflows)
- Custom workflow phases
- Webhooks and event triggers
- Batch operations with checkpointing
- Dry-run and preview modes
- Interactive prompts
- Progress bars and status displays
- Export and reporting formats
- Integration with external tools
- Custom agents or backends