Files
humanlayer/humanlayer-wui/docs/ARCHITECTURE.md
Allison Durham 11a988a068 add TypeScript types, React hooks, and UI components for web interface (for sundeep) (#214)
* refactor: reorganize daemon client to mirror Rust architecture

- Split monolithic daemon-client.ts into organized modules:
  - lib/daemon/types.ts: All TypeScript type definitions
  - lib/daemon/client.ts: DaemonClient implementation
  - lib/daemon/errors.ts: Error types
  - lib/daemon/validation.ts: Type guards and validation helpers
  - lib/daemon/index.ts: Controlled public exports
- Matches Rust daemon_client module structure for consistency
- Improves maintainability and separation of concerns

* feat: add React hooks layer for daemon interactions

- useApprovals: Manage approval requests with data enrichment
- useSessions: List and launch Claude Code sessions
- useConversation: View conversation history
- useDaemonConnection: Monitor daemon health
- Includes real-time updates via polling
- Provides loading states, error handling, and refresh functions
- Hooks handle all complexity, components just render

* feat: add UI utilities and type definitions

- UI types: UnifiedApprovalRequest for display-friendly data
- Data enrichment: Join approvals with session context
- Formatting utilities: truncate, formatTimestamp, formatParameters
- Error formatting: Convert technical errors to user-friendly messages
- Separation of UI concerns from protocol implementation

* docs: improve documentation structure and developer guides

- Update README to be concise with development section first
- Add comprehensive documentation:
  - ARCHITECTURE.md: System design with mermaid diagrams
  - DEVELOPER_GUIDE.md: Best practices and do's/don'ts
  - API.md: React hooks reference
- Clear guidance on which layer to use (hooks vs daemon client)
- Examples showing correct usage patterns for frontend developers

* formatting

* feat: add real-time subscription support and example components

- Update daemon client to support event callbacks for subscriptions
- Implement proper real-time updates in useApprovalsWithSubscription hook
- Add ApprovalsPanel component using shadcn/ui components
- Fix linting errors with proper eslint comments
- Update App.tsx imports to use new daemon module path
- Fix TypeScript return types in hooks

* feat(wui): add missing shadcn/ui components

Add card, badge, alert, and collapsible components from shadcn/ui
to resolve TypeScript import errors in ApprovalsPanel

* add react
2025-06-16 12:10:41 -07:00

3.7 KiB

Architecture Overview

System Architecture

graph LR
    subgraph "Frontend (TypeScript)"
        RC[React Component]
        RH[React Hooks]
        DC[Daemon Client]
    end

    subgraph "Tauri Bridge"
        TC[Tauri Commands<br/>src-tauri/src/lib.rs]
        RDC[Rust Daemon Client<br/>src-tauri/src/daemon_client]
    end

    subgraph "Backend"
        HLD[HumanLayer Daemon<br/>hld]
        CC[Claude Code<br/>Sessions]
    end

    RC -->|"uses"| RH
    RH -->|"calls"| DC
    DC -->|"invoke"| TC
    TC -->|"calls"| RDC
    RDC -->|"Unix Socket<br/>JSON-RPC"| HLD
    HLD -->|"manages"| CC

Data Flow Example: Approving a Function Call

sequenceDiagram
    participant UI as React Component
    participant Hook as useApprovals Hook
    participant Client as Daemon Client (TS)
    participant Tauri as Tauri Command
    participant Rust as Rust Client
    participant Daemon as HLD

    UI->>Hook: approve(callId)
    Hook->>Client: approveFunctionCall(callId)
    Client->>Tauri: invoke('approve_function_call')
    Tauri->>Rust: client.approve_function_call()
    Rust->>Daemon: JSON-RPC: sendDecision
    Daemon-->>Rust: Response
    Rust-->>Tauri: Result
    Tauri-->>Client: Success
    Client-->>Hook: void
    Hook->>Hook: refresh approvals
    Hook-->>UI: Updated state

Code Organization

Frontend (src/)

src/
├── lib/
│   └── daemon/          # Low-level daemon interface
│       ├── types.ts     # Protocol type definitions
│       ├── client.ts    # DaemonClient class
│       ├── errors.ts    # Error types
│       └── index.ts     # Public exports
├── hooks/               # React hooks layer
│   ├── useApprovals.ts  # Approval management
│   ├── useSessions.ts   # Session management
│   └── useConversation.ts
├── utils/               # UI utilities
│   ├── enrichment.ts    # Join approvals with sessions
│   └── formatting.ts    # Display formatters
├── types/
│   └── ui.ts           # UI-specific types
└── components/         # React components

Tauri Bridge (src-tauri/)

src-tauri/
├── src/
│   ├── lib.rs          # Tauri command handlers
│   └── daemon_client/  # Rust daemon client
│       ├── mod.rs      # Module exports
│       ├── types.rs    # Rust type definitions
│       ├── client.rs   # Client implementation
│       ├── connection.rs
│       └── subscriptions.rs

Key Design Principles

1. Layer Separation

  • Daemon Client: Pure protocol implementation, no UI logic
  • Hooks: React state management and data enrichment
  • Components: Presentation only, use hooks for all logic

2. Type Safety

  • Full TypeScript types matching Rust/Go protocol
  • Enums for constants (SessionStatus, ApprovalType, etc.)
  • Separate UI types for enriched data

3. Data Enrichment

  • Raw daemon data is enriched in the hooks layer
  • Approvals are joined with session context
  • UI-friendly formatting happens in TypeScript

4. Error Handling

  • Daemon errors are caught and formatted in hooks
  • User-friendly messages replace technical errors
  • Components receive simple error strings

Protocol Details

The daemon uses JSON-RPC 2.0 over Unix domain sockets. See hld/PROTOCOL.md for the full specification.

Key RPC methods:

  • launchSession - Start a new Claude Code session
  • listSessions - Get all sessions
  • fetchApprovals - Get pending approvals
  • sendDecision - Approve/deny/respond to approvals
  • getConversation - Fetch session conversation history
  • subscribe - Real-time event updates