Layr-Labs / Layr-Labs/devkit-cli

Command Guardrails for handling out of sequence cli commands and context aware error messages

Offen
#117 6 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@supernovahs arbeitet bereits daran.

Seit 21.5.2025.

enhancement
Vorherrschende Sprache
Go
Sterne
27
Forks
10
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

# Command Flow Guardrails: Dependency Management for CLI Commands

## Overview

Command Flow Guardrails detect when CLI commands are run out of expected sequence and provide context-aware error messages to guide users. This feature ensures commands like `avs call` (which depends on `avs contract-deploy`) fail gracefully with helpful guidance.

## Key Components

1. **Command Dependency Definitions**: Map of commands to their prerequisites
2. **Command History Tracking**: In-memory registry of executed commands
3. **Dependency Checking Middleware**: Validates dependencies before execution
4. **Contextual Error Messages**: Guides users to the correct next actions

## Implementation

### 1. Command Dependency Definition

```go
// CommandDependency defines a command dependency relationship
type CommandDependency struct {
Command string // Command that has dependencies
DependsOn []string // Commands that must be run before this command
ErrorMessage string // Helpful message when dependency isn't met
CheckFunc func() bool // Optional additional validation
}

// Sample dependencies
var CommandFlowDependencies = []CommandDependency{
{
Command: "call",
DependsOn: []string{"deploy-contracts"},
ErrorMessage: "The 'avs call' command requires contract deployment. " +
"Please run 'devkit avs devnet start' or 'devkit avs devnet deploy-contracts' first.",
CheckFunc: checkContractsDeployed,
},
// Other dependencies...
}
```

### 2. Command Execution Tracking

```go
// Track command execution history
var commandHistory = struct {
executedCommands map[string]bool
mu sync.Mutex
}{
executedCommands: make(map[string]bool),
}

// Record successful command execution
func recordCommandExecution(command string) {
commandHistory.mu.Lock()
defer commandHistory.mu.Unlock()
commandHistory.executedCommands[command] = true
}
```

### 3. Dependency Checking Middleware

```go
// Middleware that enforces command dependencies
func WithCommandDependencyCheck(action cli.ActionFunc) cli.ActionFunc {
return func(ctx *cli.Context) error {
cmdName := ctx.Command.Name

// Skip checks for create command (entry point)
if cmdName == "create" {
result := action(ctx)
if result == nil {
recordCommandExecution(cmdName)
}
return result
}

// Check dependencies
for _, dep := range CommandFlowDependencies {
if dep.Command == cmdName {
for _, depCmd := range dep.DependsOn {
if !hasCommandBeenExecuted(depCmd) &&
!(dep.CheckFunc != nil && dep.CheckFunc()) {
return errors.New(dep.ErrorMessage)
}
}
}
}

// Execute command and record success
result := action(ctx)
if result == nil {
recordCommandExecution(cmdName)
}
return result
}
}
```

### 4. Integration with CLI Framework

```go
func main() {

actionChain := hooks.NewActionChain()
actionChain.Use(WithCommandDependencyCheck)


hooks.ApplyMiddleware(app.Commands, actionChain)

}
```

## User Experience

When a user attempts to run a command before its prerequisites:

```bash
$ devkit avs call signature="(uint256)" args="(5)"

Error: The 'avs call' command requires contract deployment.
Please run 'devkit avs devnet start' or 'devkit avs devnet deploy-contracts' first.
```

- Users receive clear error message about the correct command sequence and next steps.

## Additional Validations

For complex dependencies that can't be verified by simple command history:

```go
// Validation function example
func checkContractsDeployed() bool {
// Check for config files with deployed contract addresses
contextPath := filepath.Join("config", "contexts", "devnet.yaml")
if _, err := os.Stat(contextPath); os.IsNotExist(err) {
return false
}

// Parse YAML and verify contract addresses exist
// [Implementation details...]

return contractsExist
}
```

## Open questions

- Is there any check that should be made for `create` command ?

## Example validations
- Check that fork url is set before devnet start is called in the context file

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.