Get the FREE Ultimate OpenClaw Setup Guide →

mutually-exclusive-group-handler

Scanned
npx machina-cli add skill a5c-ai/babysitter/mutually-exclusive-group-handler --openclaw
Files (1)
SKILL.md
4.8 KB

Mutually Exclusive Group Handler

Generate logic for handling mutually exclusive CLI argument groups.

Capabilities

  • Generate mutually exclusive group validation
  • Create dependent argument relationships
  • Set up required group validation
  • Implement custom conflict messages
  • Configure OR/XOR group logic
  • Generate documentation for groups

Usage

Invoke this skill when you need to:

  • Implement mutually exclusive options
  • Create dependent argument chains
  • Validate argument relationships
  • Generate clear conflict messages

Inputs

ParameterTypeRequiredDescription
languagestringYesTarget language
groupsarrayYesMutually exclusive group definitions

Group Structure

{
  "groups": [
    {
      "name": "output-format",
      "type": "mutually_exclusive",
      "required": true,
      "options": ["--json", "--yaml", "--table"],
      "errorMessage": "Choose one output format: --json, --yaml, or --table"
    },
    {
      "name": "auth-method",
      "type": "mutually_exclusive",
      "options": ["--token", "--username"],
      "dependencies": {
        "--username": ["--password"]
      }
    }
  ]
}

Generated Patterns

TypeScript Group Handler

interface GroupValidation {
  name: string;
  options: string[];
  required?: boolean;
  errorMessage?: string;
  dependencies?: Record<string, string[]>;
}

export function validateMutuallyExclusiveGroups(
  args: Record<string, unknown>,
  groups: GroupValidation[]
): void {
  for (const group of groups) {
    const presentOptions = group.options.filter(opt => {
      const key = opt.replace(/^--/, '').replace(/-/g, '_');
      return args[key] !== undefined;
    });

    // Check mutual exclusivity
    if (presentOptions.length > 1) {
      throw new Error(
        group.errorMessage ||
        `Options ${presentOptions.join(', ')} are mutually exclusive`
      );
    }

    // Check required group
    if (group.required && presentOptions.length === 0) {
      throw new Error(
        `One of ${group.options.join(', ')} is required`
      );
    }

    // Check dependencies
    if (group.dependencies && presentOptions.length === 1) {
      const selected = presentOptions[0];
      const deps = group.dependencies[selected];
      if (deps) {
        for (const dep of deps) {
          const depKey = dep.replace(/^--/, '').replace(/-/g, '_');
          if (args[depKey] === undefined) {
            throw new Error(
              `${selected} requires ${dep} to be specified`
            );
          }
        }
      }
    }
  }
}

Python Group Handler

from typing import Dict, List, Optional, Any

class MutuallyExclusiveGroup:
    def __init__(
        self,
        name: str,
        options: List[str],
        required: bool = False,
        error_message: Optional[str] = None,
        dependencies: Optional[Dict[str, List[str]]] = None
    ):
        self.name = name
        self.options = options
        self.required = required
        self.error_message = error_message
        self.dependencies = dependencies or {}

def validate_groups(args: Dict[str, Any], groups: List[MutuallyExclusiveGroup]) -> None:
    for group in groups:
        present = [
            opt for opt in group.options
            if args.get(opt.lstrip('-').replace('-', '_')) is not None
        ]

        # Check mutual exclusivity
        if len(present) > 1:
            raise ValueError(
                group.error_message or
                f"Options {', '.join(present)} are mutually exclusive"
            )

        # Check required
        if group.required and not present:
            raise ValueError(
                f"One of {', '.join(group.options)} is required"
            )

        # Check dependencies
        if present and group.dependencies:
            selected = present[0]
            deps = group.dependencies.get(selected, [])
            for dep in deps:
                dep_key = dep.lstrip('-').replace('-', '_')
                if args.get(dep_key) is None:
                    raise ValueError(
                        f"{selected} requires {dep} to be specified"
                    )

Workflow

  1. Define groups - Specify mutually exclusive options
  2. Set requirements - Required vs optional groups
  3. Add dependencies - Dependent argument chains
  4. Create messages - Custom error messages
  5. Generate validator - Validation logic
  6. Generate docs - Group documentation

Target Processes

  • argument-parser-setup
  • error-handling-user-feedback
  • cli-command-structure-design

Source

git clone https://github.com/a5c-ai/babysitter/blob/main/plugins/babysitter/skills/babysit/process/specializations/cli-mcp-development/skills/mutually-exclusive-group-handler/SKILL.mdView on GitHub

Overview

Mutually-exclusive-group-handler generates logic to enforce that only one option in a defined CLI group can be provided, with support for dependencies, required groups, and custom conflict messages. It covers OR/XOR logic and can generate documentation for groups to keep CLI behavior clear and predictable.

How This Skill Works

The skill takes a language target and a groups definition (name, type, options, required, dependencies, errorMessage) and emits language-specific handlers (TypeScript or Python). The generated code validates mutual exclusivity, enforces required groups, checks dependencies when one option is present, and surfaces descriptive error messages when conflicts occur.

When to Use It

  • Implement mutually exclusive options in a CLI (e.g., --json, --yaml, --table) to ensure only one format is chosen.
  • Create dependent argument chains where selecting one option requires another (e.g., --username requires --password).
  • Validate complex relationships between options and provide clear conflict messages to users.
  • Configure OR/XOR group logic to model different exclusivity rules beyond simple mutual exclusion.
  • Generate or integrate documentation for argument groups to assist users and developers.

Quick Start

  1. Step 1: Define groups as a JSON structure with name, type, options, required, dependencies, and optional errorMessage.
  2. Step 2: Invoke validateMutuallyExclusiveGroups(args, groups) (TypeScript) or validate_groups(args, groups) (Python) in your CLI bootstrap.
  3. Step 3: Handle raised errors to display user-friendly messages and exit with a non-zero status when conflicts occur.

Best Practices

  • Define a clear, user-friendly errorMessage for every group to communicate conflicts.
  • Use the dependencies map to explicitly express required relationships between options.
  • Mark groups as required when a selection from the group is mandatory for CLI operation.
  • Test all combinations: multiple options in a group, no option in a required group, and missing dependencies.
  • Keep option names consistent with the CLI parser to ensure the validator maps correctly to parsed args.

Example Use Cases

  • TypeScript Group Handler validating an output-format group with --json, --yaml, and --table, including a required flag.
  • Python Group Handler enforcing an auth-method group where --username requires --password.
  • Node.js CLI integration using the generated validators to enforce exclusive flags and present friendly errors.
  • Error message example: 'Choose one output format: --json, --yaml, or --table'.
  • Documentation generation for groups to accompany CLI help and usage guides.

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers