Skip to main content

Architecture Overview

AgentsBoard follows a strict layered architecture with SOLID principles enforced across every module.

High-Level Diagram

┌─────────────────────────────────────────────┐
│ App Layer │
│ CompositionRoot · KeyEventHandler · @main │
├─────────────────────────────────────────────┤
│ UI Layer │
│ SwiftUI Views · ViewModels · @Observable │
├─────────────────────────────────────────────┤
│ Core Layer │
│ Protocols · Domain Logic · Zero UI deps │
├─────────────────────────────────────────────┤
│ Platform / System │
│ PTY · Metal · kqueue · Unix Sockets │
└─────────────────────────────────────────────┘

Target Structure

AgentsBoard is organized as a multi-target Swift Package:

TargetTypeDependenciesPurpose
AgentsBoardExecutableCore, UIMain app entry point
AgentsBoardCoreLibrarySwiftTerm, Yams, GRDBDomain logic
AgentsBoardUILibraryCoreSwiftUI views
AgentsBoardCLIExecutableCoreCLI control tool

Key Design Decisions

Protocol-First Design

Every component is defined as a protocol before implementation. This enables:

  • Easy testing with mock implementations
  • Swappable implementations without changing consumers
  • Clear contracts between modules

Composition Root Pattern

All concrete type instantiation happens in a single place: CompositionRoot.swift. No init() calls for services exist outside this file.

@Observable for State

We use Swift's @Observable macro (not Combine) for reactive state management. This gives us:

  • Automatic view updates
  • No manual subscription management
  • Type-safe observation

Zero UI in Core

The AgentsBoardCore target has zero dependencies on SwiftUI or AppKit. This ensures domain logic is testable without a UI context.

Data Flow

User Action → View → ViewModel → Core Service → Protocol

Concrete Implementation

State Update (@Observable)

View Re-render (automatic)