Architecture - twamp22/BumbaClaude GitHub Wiki

Architecture

The Wrapper Principle

BumbaClaude is a wrapper, not a modification. It sits entirely outside Claude Code and communicates through three public interfaces:

+------------------+       tmux        +------------------+
|                  | ----------------> |                  |
|   BumbaClaude    |    filesystem     |   Claude Code    |
|   (dashboard)    | <---------------- |   (agents)       |
|                  |    Agent SDK      |                  |
+------------------+ ----------------> +------------------+

Communication Interfaces

  1. tmux sessions -- Spawns, monitors, and controls Claude Code processes

    • Spawn new agents with custom working directories and model choices
    • Capture terminal output in real-time
    • Send input to agents (messages, interrupts)
    • Kill sessions gracefully or forcefully
  2. Filesystem state -- Reads JSON files from ~/.claude/

    • Team configurations at ~/.claude/teams/{team-name}/config.json
    • Task mailbox at ~/.claude/tasks/{team-name}/
    • Agent state and message delivery
  3. Agent SDK (planned v0.2.0) -- Programmatic API for agent control

    • Cleaner agent spawning with explicit permissions
    • Better model tier selection
    • Advanced governance enforcement

Architecture Boundary

BumbaClaude NEVER:

  • Modifies files under ~/.claude/ (read-only access only)
  • Patches Claude Code's source or binary
  • Spoofs client headers or OAuth tokens
  • Bypasses rate limits or usage metering

This boundary is critical for maintainability and compliance. If a feature requires breaking this boundary, it's out of scope.

Tech Stack

Layer Technology Purpose
Desktop Electron 41+ Windows app with tray, notifications, auto-update
Framework Next.js 16+ Server-rendered React with App Router
Language TypeScript Type-safe backend and frontend
Styling Tailwind CSS Dark mode primary, utility-first design
Database SQLite via better-sqlite3 Lightweight local storage, zero config
Real-time WebSocket (ws) Live agent status and event streaming
File watching chokidar Monitor ~/.claude/ for changes
Session management tmux + child_process Spawn and control agent processes
Package manager pnpm Fast, deterministic dependency management

Directory Structure

/src/app/                          -- Next.js pages (App Router)
  layout.tsx                       -- Root layout
  page.tsx                         -- Dashboard home
  /teams
    /new                           -- Team creation wizard
      page.tsx
    /[teamId]                      -- Live monitor for team
      page.tsx
      /audit                       -- Audit log
        page.tsx
  /templates                       -- Template library
    page.tsx
  /api
    /teams                         -- Team CRUD endpoints
    /agents                        -- Agent spawning/management
    /tasks                         -- Task management
    /templates                     -- Template import/export
    /audit                         -- Audit log queries
    /ws                            -- WebSocket upgrade handler

/src/components/                   -- React components
  /dashboard                       -- Home page components
  /monitor                         -- Live monitor components
  /wizard                          -- Team creation wizard
  /templates                       -- Template UI
  /shared                          -- Reusable components

/src/lib/                          -- Core library code
  db.ts                            -- SQLite connection + helpers
  tmux.ts                          -- tmux command wrappers
  watcher.ts                       -- ~/.claude/ file watcher
  websocket.ts                     -- WebSocket server
  types.ts                         -- Shared TypeScript types

/src/hooks/                        -- Custom React hooks
  useTeamStatus.ts                 -- Live team status via WebSocket
  useAuditLog.ts                   -- Stream audit events

/db/
  schema.sql                       -- SQLite schema
  seed.sql                         -- Default templates

/electron/                         -- Electron main process (dev build only)
  main.ts                          -- Window and IPC management
  preload.ts                       -- Renderer<->main bridge
  tray.ts                          -- System tray icon/menu
  updater.ts                       -- Auto-update logic
  notifications.ts                 -- Native OS notifications

/data/
  dashboard.db                     -- SQLite database (auto-created)

Database Schema

All data persists in a single SQLite database at ./data/dashboard.db.

Core tables

teams -- Agent team configurations

  • id (text) -- UUID
  • name (text) -- User-friendly name
  • project_dir (text) -- Working directory path
  • status (text) -- running, paused, completed, errored
  • execution_mode (text) -- tmux (v0.1) or sdk (v0.2+)
  • created_at, ended_at (datetime) -- Timestamps

agents -- Team members

  • id (text) -- UUID
  • team_id (text) -- FK to teams
  • name, role (text) -- Agent identity
  • model_tier (text) -- haiku, sonnet, opus
  • system_prompt (text) -- Custom instructions
  • status (text) -- idle, working, waiting, completed, errored
  • tmux_session (text) -- tmux session:pane identifier
  • spawned_at, ended_at (datetime)

tasks -- Work items

  • id (text) -- UUID
  • team_id (text) -- FK to teams
  • title, description (text) -- Task content
  • assigned_agent_id (text) -- FK to agents (nullable)
  • created_by_agent_id (text) -- FK to agents (nullable)
  • parent_task_id (text) -- FK to tasks (nullable, for hierarchies)
  • status (text) -- pending, claimed, in_progress, review, completed, blocked
  • created_at, completed_at (datetime)

governance_rules -- Permission boundaries

  • id (text) -- UUID
  • team_id (text) -- FK to teams
  • rule_type (text) -- can_create_files, can_run_commands, can_push_git, max_turns
  • rule_value (text) -- 'true'/'false' or numeric string

audit_events -- Complete activity history

  • id (integer) -- Auto-increment
  • team_id (text) -- FK to teams
  • agent_id (text) -- FK to agents (nullable)
  • event_type (text) -- agent_spawned, task_created, error, etc.
  • event_data (text) -- JSON blob with event-specific details
  • created_at (datetime)

templates -- Reusable team configs

  • id (text) -- UUID
  • name (text) -- Template name
  • description (text) -- What the template does
  • config (text) -- JSON: { agents: [...], governance: {...}, prompts: {...} }
  • created_at, updated_at (datetime)

token_usage -- LLM token tracking

  • id (integer) -- Auto-increment
  • team_id, agent_id (text) -- FK references
  • input_tokens, output_tokens (integer)
  • cache_read_tokens, cache_creation_tokens (integer)
  • cost_usd (real) -- Estimated cost
  • model (text) -- Model used (haiku, sonnet, opus)
  • duration_ms (integer) -- Response time
  • session_id (text) -- Agent session ID
  • recorded_at (datetime)

tool_usage -- Tool invocation tracking

  • id (integer) -- Auto-increment
  • team_id, agent_id (text) -- FK references
  • tool_name (text) -- Tool invoked
  • tool_input_summary (text) -- First 200 chars of tool input
  • is_mcp_tool (integer) -- Boolean: 0=built-in, 1=MCP
  • mcp_server_name (text) -- MCP server name (if applicable)
  • recorded_at (datetime)

schedules -- Recurring tasks

  • id (text) -- UUID
  • team_id, agent_id (text) -- FK references
  • name (text) -- Schedule name
  • schedule_type (text) -- 'interval' or 'cron'
  • schedule_value (text) -- ms for interval, cron expression for cron
  • message (text) -- Task message to send
  • enabled (integer) -- Boolean: 1=on, 0=off
  • last_run_at (datetime) -- When it last ran
  • run_count (integer) -- Total executions
  • created_at (datetime)

mcp_servers -- MCP server registry

  • id (integer) -- Auto-increment
  • team_id, agent_id (text) -- FK references (nullable)
  • server_name (text) -- MCP server name
  • status (text) -- Server status
  • source (text) -- 'agent-stream', 'project-config', or 'global-config'
  • discovered_at (datetime)

Backend API Routes

All API routes are in /src/app/api/.

Team management

  • POST /api/teams -- Create new team
  • GET /api/teams -- List all teams
  • GET /api/teams/[teamId] -- Get team details
  • PATCH /api/teams/[teamId] -- Update team
  • POST /api/teams/[teamId]/end -- Graceful shutdown
  • POST /api/teams/[teamId]/kill -- Force termination

Agent management

  • POST /api/teams/[teamId]/agents -- Spawn new agent
  • GET /api/teams/[teamId]/agents -- List team agents
  • POST /api/agents/[agentId]/message -- Send message to agent
  • POST /api/agents/[agentId]/interrupt -- Send Ctrl+C

Task management

  • GET /api/teams/[teamId]/tasks -- List tasks
  • POST /api/teams/[teamId]/tasks -- Create task
  • PATCH /api/tasks/[taskId] -- Update task status

Audit log

  • GET /api/teams/[teamId]/audit -- Stream audit events

Templates

  • GET /api/templates -- List templates
  • POST /api/templates -- Save template
  • POST /api/templates/[templateId]/export -- Export as JSON
  • POST /api/templates/import -- Import from JSON

WebSocket

  • GET /api/ws -- Upgrade to WebSocket for live updates

Electron Packaging

The Electron layer wraps the built Next.js app. Build process:

  1. Compile Next.js with pnpm build (output: standalone)
  2. Compile Electron TypeScript files with tsc
  3. Package using electron-builder with NSIS installer
  4. Create portable zip as an alternative distribution

The Next.js app starts as a child process in the Electron main process. The renderer connects to http://localhost:{port} where the Next.js server runs.

Real-time Updates (WebSocket)

The dashboard uses WebSocket for live agent status and event streaming.

Connection flow:

  1. Client opens WebSocket connection to /api/ws
  2. Server upgrades HTTP to WebSocket
  3. Client subscribes to team events: { action: "subscribe", teamId: "..." }
  4. Server sends events as JSON: { type: "agent_status_changed", data: {...} }
  5. Client updates UI without page reload

Supported events:

  • agent_status_changed -- Agent status update
  • task_created / task_updated -- Task changes
  • audit_event -- New audit log entry
  • agent_output -- Terminal output line

This enables live monitoring without polling.

File Watching

The watcher (lib/watcher.ts) uses chokidar to monitor ~/.claude/:

  • ~/.claude/teams/{teamName}/config.json -- Team membership
  • ~/.claude/tasks/{teamName}/*.pending -- New tasks
  • ~/.claude/tasks/{teamName}/*.lock -- Task claims
  • ~/.claude/messages/{teamName}/*.json -- Agent messages

On file changes, the watcher parses the JSON and emits events. These feed the audit log and real-time dashboard updates.

Error Handling

All critical operations wrap in try/catch:

  • Database queries: Return error in response body
  • tmux commands: Retry with exponential backoff if transient
  • File I/O: Log to console.error, notify user via UI
  • WebSocket: Graceful disconnect and auto-reconnect on client

Silent failures are never acceptable. Users always see meaningful error messages.