b7b05bb4e341201a31122a2d0cb2aae397d70fc8
Move registerEventHandlers() call before the readLoop goroutine starts in connectAndRun(). This eliminates the startup window where live gateway events were actively read and dropped as 'unhandled' because handler registration happened only after initialSync completed. The handlers only depend on c.agents and c.broker, which are wired in the constructor — they do not require initialSync to have completed. Also adds TestConnectAndRun_EventNotLostDuringSync regression test that sends a live presence event during initial sync and asserts it is not lost. All gateway tests pass with -race.
CUB-200: resolve merge conflicts with dev — adopt dev's consolidated workflows and improved Go gateway code
Control Center
Real-time agent fleet dashboard for the OpenClaw AI development team.
Control Center monitors and controls the full CubeCraft Creations AI agent fleet — Otto, Rex, Dex, Hex, Pip, Nano, Sketch, Bob, Stuart, Norbert, and Flip. It provides live agent status, task progress, session logs, and a command interface, backed by SignalR for push-based updates directly from the OpenClaw gateway.
Tech Stack
| Layer | Technology |
|---|---|
| Backend | ASP.NET Core Web API (.NET 8) |
| Database | PostgreSQL (snake_case via EF Core) |
| ORM | Entity Framework Core |
| Real-time | SignalR (AgentStatusHub) |
| Frontend | Angular (latest), Angular Material, Angular Signals |
| API Client | TypeScript package (api-client/) |
| Deployment | Docker |
Project Structure
Control-Center/
├── backend/
│ ├── ControlCenter/
│ │ ├── Controllers/ # AgentsController, CommandController, LogsController
│ │ ├── Hubs/ # AgentStatusHub, IAgentStatusClient, AgentStatusModels
│ │ ├── Models/ # AgentMinionMapping
│ │ ├── Services/ # AgentMinionMapperService, GatewayEventBridgeService
│ │ ├── Program.cs
│ │ └── appsettings.json
│ ├── Configurations/ # AgentConfiguration
│ ├── Data/ # AppDbContext, AppDbContextFactory
│ ├── Dtos/ # AgentStatusUpdateDto
│ ├── Entities/ # Agent, AgentStatus
│ ├── Migrations/ # EF migrations
│ ├── Models/ # AgentState
│ └── Repositories/ # AgentStateRepository, IAgentStateRepository
├── frontend/
│ └── src/app/
│ ├── layout/ # LayoutShell, HeaderBar, NavRail, BottomNav
│ ├── pages/ # hub, logs, projects, sessions, settings
│ ├── components/ # AgentCard, AgentStatusBadge, TaskProgressBar,
│ │ # QuickJumpButton, QuickJumpDrawer,
│ │ # GlobalActionModal, AdaptiveNavigation
│ ├── command-hub/ # AgentCard command hub view
│ ├── models/ # Agent model, AgentStatus, AgentCardData, Nav
│ └── services/ # AgentStatusService (Angular Signals)
├── api-client/ # Shared TS client (models, SignalR WS, HTTP utils)
├── design/
│ ├── command-hub-spec.md
│ └── mockups/ # Desktop kiosk, mobile, quick-jump drawer
└── README.md
Domain Model
Agent
| Field | Type | Description |
|---|---|---|
Id |
Guid |
Primary key |
Status |
AgentStatus |
Current agent state |
Task |
string? |
Active task description |
Progress |
int? |
Task completion % (0–100) |
SessionKey |
string |
OpenClaw session identifier |
Channel |
string |
Source channel (telegram, slack, etc.) |
LastActivity |
DateTime |
Last event timestamp |
CreatedAt / UpdatedAt |
DateTime |
Audit fields |
AgentStatus enum
| Value | Integer | Meaning |
|---|---|---|
Active |
0 | Agent is executing a task |
Idle |
1 | Agent is waiting for work |
Thinking |
2 | Agent is reasoning/planning |
Error |
3 | Agent hit an unrecoverable state |
Key Design Decisions
- Angular Signals — Reactive state management. No NgRx — kept intentionally simple.
- Adaptive layout — Sidebar nav (NavRail) on desktop/kiosk (≥768px); bottom nav on mobile.
- Tactical Dark Mode — Theme via CSS custom properties in
styles.scss. - SignalR fleet group — Clients call
JoinFleet()to subscribe to all agent updates broadcast by the hub. - Backend push model — Hub uses
IHubContext<AgentStatusHub, IAgentStatusClient>extension methods to push to clients; no polling. - Gateway bridge —
GatewayEventBridgeServiceconnects the OpenClaw gateway WebSocket to the SignalR hub.
Getting Started
Prerequisites
- .NET 8 SDK
- Node.js 20+
- Docker
- PostgreSQL
- Running OpenClaw gateway (for live agent events)
Backend
cd backend
# Restore and build
dotnet restore
dotnet build
# Apply migrations
dotnet ef database update --project ControlCenter
# Run API
dotnet run --project ControlCenter
API runs at http://localhost:5000 · Swagger at http://localhost:5000/swagger
Frontend
cd frontend
npm install
ng serve
Frontend runs at http://localhost:4200
Configuration
backend/ControlCenter/appsettings.json — override in appsettings.Development.json or environment variables:
| Key | Default | Description |
|---|---|---|
ConnectionStrings:DefaultConnection |
(set in dev config) | PostgreSQL connection string |
Gateway:WebSocketUrl |
ws://localhost:3271/ws |
OpenClaw gateway WebSocket URL |
Gateway:AuthToken |
"" |
Gateway auth token |
Cors:AllowedOrigins |
localhost:4200, localhost:5000 |
Frontend origins for CORS |
Real-Time Events
SignalR hub endpoint: /hubs/agent-status
Hub Methods (server → client)
| Method | Payload | Description |
|---|---|---|
ReceiveStatusUpdate |
AgentStatusUpdateDto |
Agent status changed |
ReceiveAgentList |
Agent[] |
Full fleet snapshot on join |
Client → Server
| Method | Description |
|---|---|
JoinFleet() |
Subscribe to all agent updates |
LeaveFleet() |
Unsubscribe |
SendStatusUpdate(dto) |
Push a status update (internal use) |
Pages
| Route | Page | Description |
|---|---|---|
/hub |
Command Hub | Live agent grid — status, task, progress |
/logs |
Logs | Agent session log viewer |
/projects |
Projects | Linear project tracking view |
/sessions |
Sessions | OpenClaw session browser |
/settings |
Settings | App configuration |
Agent Fleet
| Agent | Role |
|---|---|
| Otto | Orchestrator — owns the dev lifecycle |
| Rex | Frontend (Angular) |
| Dex | Backend (ASP.NET Core) |
| Hex | Database (schema, migrations) |
| Pip | Raspberry Pi / Python |
| Nano | Arduino / ESP32 / ESPHome |
| Sketch | UX/UI design |
| Flip | Mobile development |
| Bob | Content & marketing copy |
| Stuart | Concept visualization (images) |
| Norbert | 3D design (OpenSCAD) |
Branch & PR Rules
- All feature branches target
dev— nevermain - Branch naming:
agent/<agent>/CUB-N-short-description - PR titles:
CUB-N: short description - PRs require Otto review before Joshua merges
API Overview
| Route prefix | Resource |
|---|---|
/api/agents |
Agent registry and status |
/api/command |
Issue commands to agents |
/api/logs |
Session log retrieval |
Full schema at /swagger when running in dev.
Built by CubeCraft Creations · Orchestrated by Otto
Description
Languages
TypeScript
34.1%
Go
26.6%
SCSS
17.9%
C#
15.2%
HTML
4.6%
Other
1.6%