Skip to content

🏛️ Architecture Documentation

Internal architecture and design decisions for CapiscIO CLI

Design Philosophy

Core Principles:

  • Zero External Dependencies: No reliance on external validator services
  • Modularity: Clean separation of concerns for easy maintenance
  • Extensibility: Simple to add new validation rules
  • Performance: Efficient validation with minimal overhead
  • Reliability: Comprehensive error handling and graceful degradation

This document outlines the internal architecture, design patterns, and technical decisions behind the CapiscIO CLI validation system.

📚 Table of Contents

Overview

The CapiscIO CLI is designed as a self-contained, performant validation tool for A2A protocol agent cards. The architecture prioritizes:

  • Zero External Dependencies: No reliance on external validator services
  • Modularity: Clean separation of concerns
  • Extensibility: Easy to add new validation rules
  • Performance: Efficient validation with minimal overhead
  • Reliability: Comprehensive error handling and graceful degradation

Core Components

Component Diagram

graph TB
    CLI[CLI Layer<br/>cli.ts<br/>Command Registration]
    CMD[Commands<br/>validate.ts<br/>ValidateCmd]
    OUT[Output<br/>console.ts<br/>json.ts]

    UTIL[Utilities<br/>file-utils.ts<br/>semver.ts]
    VAL[Validator<br/>a2a-validator.ts]
    HTTP[HTTP Client<br/>http-client.ts]

    TYPES[Type System<br/>AgentCard, ValidationResult<br/>ValidationOptions, ValidationError<br/>TransportProtocol, CLIOptions]

    CLI --> CMD
    CMD --> OUT
    CMD --> VAL
    VAL --> UTIL
    VAL --> HTTP
    CLI -.-> TYPES
    CMD -.-> TYPES
    VAL -.-> TYPES
    OUT -.-> TYPES

Layer Responsibilities

1. CLI Layer (src/cli.ts)

  • Entry point and command registration
  • Global error handling
  • Version management
  • Commander.js integration

2. Command Layer (src/commands/)

  • Command-specific logic
  • Option parsing and validation
  • User interaction (spinners, prompts)
  • Result formatting coordination

3. Validator Layer (src/validator/)

  • Core validation logic
  • Schema validation
  • Version compatibility checking
  • Network endpoint testing

4. Output Layer (src/output/)

  • Result formatting and display
  • Console output with colors and styling
  • JSON output for CI/CD integration

5. Utility Layer (src/utils/)

  • File system operations
  • Semver utilities
  • Helper functions

6. Type Layer (src/types/)

  • TypeScript type definitions
  • Interface contracts
  • Type safety enforcement

Data Flow

Validation Flow Diagram

graph TB
    USER[User Input] --> PARSE[Command Parser]
    PARSE --> RESOLVE[Input Resolution<br/>File or URL Detection]
    RESOLVE --> LOAD[Load Agent Card Data]
    LOAD --> VALIDATOR[A2A Validator]

    VALIDATOR --> SCHEMA[Schema Validation]
    VALIDATOR --> VERSION[Version Compatibility]
    VALIDATOR --> NETWORK[Network Testing]

    SCHEMA --> RESULT[Validation Result]
    VERSION --> RESULT
    NETWORK --> RESULT

    RESULT --> FORMATTER[Output Formatter]
    FORMATTER --> OUTPUT[Console or JSON Output]

Processing Pipeline

  1. Input Processing
  2. Parse CLI arguments
  3. Resolve input type (file/URL/auto-detect)
  4. Load agent card data

  5. Validation Pipeline

  6. Schema validation
  7. Version compatibility analysis
  8. Network endpoint testing (if applicable)
  9. Feature detection and warnings

  10. Result Aggregation

  11. Collect errors, warnings, suggestions
  12. Calculate validation score
  13. Generate timing metrics

  14. Output Generation

  15. Format results for console or JSON
  16. Apply styling and colors
  17. Display actionable feedback

Design Patterns

1. Strategy Pattern (Validation Modes)

// Validation strategies
interface ValidationStrategy {
  validate(card: AgentCard): ValidationResult;
}

class ProgressiveStrategy implements ValidationStrategy {
  validate(card: AgentCard): ValidationResult {
    // Progressive validation logic
  }
}

class StrictStrategy implements ValidationStrategy {
  validate(card: AgentCard): ValidationResult {
    // Strict validation logic
  }
}

2. Dependency Injection (HTTP Client)

class A2AValidator {
  constructor(private httpClient: HttpClient = new FetchHttpClient()) {
    // Allows custom HTTP client injection for testing
  }
}

3. Factory Pattern (Output Formatters)

function createOutputFormatter(format: 'json' | 'console'): OutputFormatter {
  return format === 'json' ? new JsonOutput() : new ConsoleOutput();
}

4. Command Pattern (CLI Commands)

abstract class Command {
  abstract execute(args: string[], options: CLIOptions): Promise<void>;
}

class ValidateCommand extends Command {
  async execute(args: string[], options: CLIOptions): Promise<void> {
    // Validation command implementation
  }
}

5. Builder Pattern (Validation Options)

class ValidationOptionsBuilder {
  private options: ValidationOptions = {};

  strictness(level: ValidationStrictness): this {
    this.options.strictness = level;
    return this;
  }

  timeout(ms: number): this {
    this.options.timeout = ms;
    return this;
  }

  build(): ValidationOptions {
    return { ...this.options };
  }
}

Dependency Management

Production Dependencies

Package Purpose Justification
commander CLI framework Industry standard, well-maintained
chalk Console colors Enhanced user experience
ora Loading spinners Visual feedback for long operations
inquirer Interactive prompts Future extension capability
glob File pattern matching Auto-detection functionality

Zero External Service Dependencies

  • No axios: Uses native fetch() API
  • No semver package: Custom lightweight implementation
  • No external validators: Embedded validation logic
  • No cloud services: Completely self-contained

Bundle Size Optimization

# Production bundle analysis
npm run build

# Outputs:
# dist/cli.js     ~27KB (minified)
# dist/index.js   ~26KB (library)
# dist/index.d.ts ~7KB  (types)

Performance Considerations

Optimization Strategies

  1. Lazy Loading

    // Only load validation rules when needed
    const loadValidationRules = () => import('./validation-rules');
    

  2. Caching

    // Cache semver comparisons
    const versionCache = new Map<string, boolean>();
    

  3. Early Termination

    // Stop validation on critical errors
    if (criticalError) {
      return { success: false, errors: [criticalError] };
    }
    

  4. Parallel Processing

    // Validate multiple aspects concurrently
    const [schemaResult, versionResult] = await Promise.all([
      validateSchema(card),
      validateVersion(card)
    ]);
    

Memory Management

  • Streaming JSON parsing for large files
  • Cleanup of HTTP connections
  • Garbage collection-friendly patterns

Performance Benchmarks

Operation Average Time Memory Usage
Schema validation 1-10ms 1-5MB
Network request 50-500ms 1-2MB
File parsing 1-5ms 1-3MB
Total validation 100-1000ms 5-15MB

Extensibility

Adding New Validation Rules

// src/validator/rules/custom-rule.ts
export class CustomValidationRule {
  validate(card: AgentCard): ValidationError[] {
    const errors: ValidationError[] = [];

    // Custom validation logic
    if (customCondition(card)) {
      errors.push({
        code: 'CUSTOM_ERROR',
        message: 'Custom validation failed',
        severity: 'error'
      });
    }

    return errors;
  }
}

// Register in validator
validator.addRule(new CustomValidationRule());

Custom Output Formatters

// src/output/xml-output.ts
export class XmlOutput implements OutputFormatter {
  display(result: ValidationResult): void {
    const xml = this.convertToXml(result);
    console.log(xml);
  }

  private convertToXml(result: ValidationResult): string {
    // XML conversion logic
  }
}

Plugin Architecture (Future)

// Future plugin system design
interface ValidationPlugin {
  name: string;
  version: string;
  validate(card: AgentCard, options: ValidationOptions): Promise<PluginResult>;
}

class PluginManager {
  private plugins: ValidationPlugin[] = [];

  register(plugin: ValidationPlugin): void {
    this.plugins.push(plugin);
  }

  async runPlugins(card: AgentCard): Promise<PluginResult[]> {
    return Promise.all(
      this.plugins.map(plugin => plugin.validate(card, {}))
    );
  }
}

Configuration System (Future)

// .capiscio.config.js
export default {
  validation: {
    strictness: 'progressive',
    timeout: 10000,
    rules: {
      'schema-validation': { enabled: true },
      'version-compatibility': { enabled: true },
      'custom-rule': { enabled: false }
    }
  },
  output: {
    format: 'console',
    colors: true,
    verbose: false
  }
};

Testing Architecture

Test Structure

tests/
├── unit/
│   ├── validator.test.ts
│   ├── http-client.test.ts
│   └── utils.test.ts
├── integration/
│   ├── cli.test.ts
│   └── end-to-end.test.ts
└── fixtures/
    ├── valid-agents/
    └── invalid-agents/

Testing Patterns

  1. Unit Tests: Individual component testing
  2. Integration Tests: Component interaction testing
  3. E2E Tests: Full CLI workflow testing
  4. Mock Strategy: HTTP client mocking for network tests

See Also

Building an Agent?

This document is for extending capiscio-cli. If you're building an A2A agent, see CapiscIO A2A Security for runtime protection.

Maintenance & Evolution

Version Management

  • Semantic versioning for public API
  • Internal API versioning for extensions
  • Backward compatibility guarantees

Code Quality

  • TypeScript strict mode
  • ESLint with custom rules
  • Automated testing in CI
  • Code coverage requirements

Performance Monitoring

  • Validation timing metrics
  • Memory usage tracking
  • Bundle size monitoring
  • Performance regression testing

This architecture provides a solid foundation for the current CLI while enabling future growth and extensibility.