Documentation
¶
Overview ¶
Package cli provides the Cobra-based command-line interface for AWF.
The CLI layer is the primary user-facing entry point, translating command-line invocations into application service calls. All commands follow the hexagonal architecture pattern: CLI → Application Services → Domain → Infrastructure. The package handles user input collection, output formatting, signal handling, and exit code mapping according to the AWF error taxonomy.
Architecture Role ¶
In the hexagonal architecture:
- CLI commands receive user input from cobra.Command flags and arguments
- Commands delegate business logic to application services (WorkflowService, ExecutionService)
- Commands handle cross-cutting concerns: signal handling, exit codes, output formatting
- Commands inject infrastructure adapters (repositories, loggers, executors) into services
The CLI layer is an adapter in the "interfaces" layer, depending on both application services (orchestration) and infrastructure adapters (implementation details). No domain logic resides here—only input parsing, output rendering, and coordination.
Command Structure ¶
## Root Command (root.go)
Application container and version command:
- App: Dependency injection container with Config and Formatter
- NewApp: Creates application with loaded configuration
- NewRootCommand: Builds cobra command tree with global flags
- newVersionCommand: Displays AWF version, commit, and build date
Global flags:
- --no-color: Disable colorized output
- --json: JSON-formatted output
- --no-hints: Suppress helpful tips
## Core Commands
### run (run.go)
Execute workflow with state machine traversal:
- Flags: --input, --resume, --agent-input, --mock, --dry-run, --interactive, --no-save
- Input resolution: CLI flags → project config → interactive prompts
- Dry run mode: validates without execution, renders execution plan
- Interactive mode: step-by-step execution with user confirmation
- Resume support: continues from saved checkpoint state
- Error categorization: maps domain/infra errors to exit codes (1-4)
### list (list.go)
Enumerate available workflows and prompts:
- list: Display all workflows from configured paths
- list prompts: Show available interactive prompts with descriptions
- Output format: table (default) or JSON
### validate (validate.go)
Static workflow validation:
- Parse workflow YAML
- Validate structure, state references, transitions
- Check for cycles, unreachable states
- Exit 0 on success, 2 on validation errors
### status (status.go)
Check running workflow status:
- Query execution state from StateStore
- Display current step, progress, outputs
- Show execution timeline and duration
### resume (resume.go)
Continue interrupted workflow:
- Load checkpoint state from StateStore
- Resume execution from last completed step
- Preserve input values and outputs
### history (history.go)
Query workflow execution history:
- List past executions with filtering (workflow name, status, date range)
- Show execution statistics (duration, success rate)
- Prune old history records
## Supporting Commands
### init (init.go)
Initialize AWF in current directory:
- Create .awf/ directory structure
- Generate default awf.yaml configuration
- Create workflows/ directory with example
### config (config.go, config_cmd.go)
Configuration management:
- config show: Display current configuration
- config set <key> <value>: Update configuration value
- config paths: Show search paths for workflows/templates/plugins
### plugin (plugin_cmd.go, plugins.go)
Plugin lifecycle management:
- plugin list: Show available plugins
- plugin enable <name>: Activate plugin
- plugin disable <name>: Deactivate plugin
- plugin status <name>: Check plugin state
### diagram (diagram.go)
Generate workflow visualization:
- Render workflow state machine as Mermaid diagram
- Output to stdout or file
### migration (migration.go)
Version migration utilities:
- Migrate workflow syntax to latest version
- Update deprecated fields
Signal Handling (signal_handler.go) ¶
Graceful shutdown on SIGINT/SIGTERM:
- setupSignalHandler: Starts goroutine listening for OS signals
- Context cancellation: Propagates cancellation through execution stack
- Process group cleanup: Terminates child processes on signal
- Cleanup callback: Executes user-provided cleanup function before exit
- Goroutine leak prevention: Returns cleanup function that MUST be deferred
Exit Codes (exitcodes.go) ¶
AWF error taxonomy mapping:
- ExitSuccess (0): Successful execution
- ExitUser (1): User error (bad input, missing file, invalid flags)
- ExitWorkflow (2): Workflow error (invalid state reference, cycle detection, schema violation)
- ExitExecution (3): Execution error (command failed, timeout, agent error)
- ExitSystem (4): System error (IO failure, permissions, resource exhaustion)
Error Handling (error.go) ¶
Error categorization and formatting:
- exitError: Wraps domain/infra errors with exit code
- categorizeError: Maps error types to exit codes via taxonomy
- writeErrorAndExit: Formats error, writes to stderr, exits with correct code
- formatLog: Colorized log output with level-based styling
Design Principles ¶
- Thin adapter layer: All business logic in application/domain layers
- Fail fast: Validate inputs before service calls
- User-friendly errors: Context-rich messages with actionable guidance
- Testability: Commands accept io.Writer for output, injectable services
- Signal safety: Always defer signal handler cleanup to prevent leaks
- Exit code discipline: Consistent taxonomy mapping for automation/scripting
Index ¶
- Constants
- Variables
- func BuildPluginPaths() []repository.SourcedPath
- func BuildPromptPaths() []repository.SourcedPath
- func BuildWorkflowPaths() []repository.SourcedPath
- func CheckMigration(w io.Writer)
- func NewRootCommand() *cobra.Command
- func NewWorkflowRepository() *repository.CompositeRepository
- func ParseMockFlags(flags []string) (map[string]string, error)
- func RenderWorkflowHelp(cmd *cobra.Command, wf *workflow.Workflow, out io.Writer, noColor bool) error
- type App
- type Config
- type ConfigShowOutput
- type HistoryInfo
- type HistoryStatsInfo
- type OutputMode
- type PluginSystemResult
Constants ¶
const ( ExitSuccess = 0 // Success ExitUser = 1 // User error (bad input, missing file) ExitWorkflow = 2 // Workflow error (invalid state reference, cycle) ExitExecution = 3 // Execution error (command failed, timeout) ExitSystem = 4 // System error (IO, permissions) )
Exit codes following the error taxonomy
Variables ¶
var ( Version = "dev" Commit = "unknown" BuildDate = "unknown" )
Version information (set at build time via ldflags)
Functions ¶
func BuildPluginPaths ¶
func BuildPluginPaths() []repository.SourcedPath
BuildPluginPaths returns plugin paths in priority order: 1. AWF_PLUGINS_PATH env var 2. ./.awf/plugins/ (local project) 3. $XDG_DATA_HOME/awf/plugins/ (global)
func BuildPromptPaths ¶
func BuildPromptPaths() []repository.SourcedPath
BuildPromptPaths returns the prompt paths in priority order: 1. ./.awf/prompts/ (local project) 2. $XDG_CONFIG_HOME/awf/prompts/ (global)
func BuildWorkflowPaths ¶
func BuildWorkflowPaths() []repository.SourcedPath
BuildWorkflowPaths returns the workflow paths in priority order: 1. AWF_WORKFLOWS_PATH env var 2. ./.awf/workflows/ (local project) 3. $XDG_CONFIG_HOME/awf/workflows/ (global)
func CheckMigration ¶
CheckMigration shows a one-time migration notice if ~/.awf exists
func NewRootCommand ¶
func NewWorkflowRepository ¶
func NewWorkflowRepository() *repository.CompositeRepository
NewWorkflowRepository creates a CompositeRepository with standard paths
func ParseMockFlags ¶
ParseMockFlags parses --mock flags into a map. Format: states.step_name.Output=value
func RenderWorkflowHelp ¶
func RenderWorkflowHelp(cmd *cobra.Command, wf *workflow.Workflow, out io.Writer, noColor bool) error
RenderWorkflowHelp renders workflow-specific help output including workflow description and input parameters table. This is called when a user runs `awf run <workflow> --help` to display dynamic help for the specified workflow.
The output follows Cobra help conventions while adding workflow-specific content: - Workflow description (if present) - Input parameters table with NAME, TYPE, REQUIRED, DEFAULT, DESCRIPTION columns
Types ¶
type Config ¶
type Config struct {
Verbose bool
Quiet bool
NoColor bool
NoHints bool
OutputMode OutputMode
OutputFormat ui.OutputFormat
LogLevel string
ConfigPath string
StoragePath string
PluginsDir string // Override plugin discovery directory (empty = use BuildPluginPaths)
}
Config holds CLI configuration.
type ConfigShowOutput ¶
type ConfigShowOutput struct {
Path string `json:"path"`
Exists bool `json:"exists"`
Inputs map[string]any `json:"inputs,omitempty"`
}
ConfigShowOutput represents the structured output for 'config show' command. Used for JSON format output.
type HistoryInfo ¶
type HistoryInfo struct {
ID string `json:"id"`
WorkflowID string `json:"workflow_id"`
WorkflowName string `json:"workflow_name"`
Status string `json:"status"`
ExitCode int `json:"exit_code,omitempty"`
StartedAt string `json:"started_at"`
CompletedAt string `json:"completed_at"`
DurationMs int64 `json:"duration_ms"`
ErrorMessage string `json:"error_message,omitempty"`
}
HistoryInfo is the JSON/output structure for history command.
type HistoryStatsInfo ¶
type HistoryStatsInfo struct {
TotalExecutions int `json:"total_executions"`
SuccessCount int `json:"success_count"`
FailedCount int `json:"failed_count"`
CancelledCount int `json:"cancelled_count"`
AvgDurationMs int64 `json:"avg_duration_ms"`
}
HistoryStatsInfo is the JSON/output structure for history stats.
type OutputMode ¶
type OutputMode int
OutputMode defines how command output is displayed.
const ( OutputSilent OutputMode = iota // default: no streaming OutputStreaming // real-time prefixed output OutputBuffered // show after completion )
func ParseOutputMode ¶
func ParseOutputMode(s string) (OutputMode, error)
ParseOutputMode parses a string to OutputMode.
func (OutputMode) String ¶
func (m OutputMode) String() string
type PluginSystemResult ¶
type PluginSystemResult struct {
Service *application.PluginService
Manager ports.OperationProvider
RPCManager *infrastructurePlugin.RPCPluginManager // for validator/step-type providers (C069)
StateStore *infrastructurePlugin.JSONPluginStateStore
Cleanup func()
}
PluginSystemResult contains the initialized plugin system components.