Files
opencode-krates-connector/design/architecture.md
Hermes Agent 78f19cde7d feat: Add comprehensive design documentation for Krates
- Canvas: Infinite zoomable workspace with LOD and navigation
- Spotlight: Fuzzy search with type filters and view shortcuts
- Krate: Window group container with non-overlapping placement
- Detail Window: YAML/Describe/Logs/Shell views with maximize
- Top Bar: Cluster info, user presence, admin toggle
- Admin Drawer: Multi-user presence and spectate functionality
- Minimap: Browse and navigate canvas overview
- Collection Window: List/tree views with filtering and sorting
- Shell/Logs: Real-time terminal and log streaming
- Backend: Go service with K8s API, WebSocket handlers, CRDT sync
- Architecture: Full project structure and tech stack
2026-06-16 08:32:47 -04:00

7.9 KiB

Top-Level Application Architecture

Tech Stack Recommendations

Frontend

  • Framework: React 18 + TypeScript
  • Styling: CSS-in-JS (styled-components or vanilla-extract) or Tailwind CSS
  • Terminal: xterm.js
  • Real-Time: Yjs + y-websocket (CRDT collaboration)
  • Build Tool: Vite
  • Fonts: IBM Plex Sans + IBM Plex Mono (Google Fonts or self-hosted)
  • State Management: Zustand or React Context (keep it simple)

Backend

  • Language: Go
  • Kubernetes Client: kubernetes/client-go
  • WebSockets: gorilla/websocket
  • CRDT Backend: Redis (single-node) or y-leveldb/y-mongodb (multi-node)
  • Build/Deployment: Docker, Kubernetes

Project Structure

krates/
├── client/                     # Frontend application
│   ├── src/
│   │   ├── components/        # React components
│   │   │   ├── canvas/       # Canvas and world layer
│   │   │   │   ├── WorldLayer.tsx
│   │   │   │   ├── GridOverlay.tsx
│   │   │   │   └── Minimap.tsx
│   │   │   ├── krate/        # Krate and windows
│   │   │   │   ├── Krate.tsx
│   │   │   │   ├── KrateHeader.tsx
│   │   │   │   ├── DetailWindow.tsx
│   │   │   │   └── CollectionWindow.tsx
│   │   │   ├── Spotlight.tsx
│   │   │   ├── TopBar.tsx
│   │   │   ├── AdminDrawer.tsx
│   │   │   ├── ShellTerminal.tsx  # xterm.js wrapper
│   │   │   └── LogsViewer.tsx
│   │   ├── hooks/            # Custom React hooks
│   │   │   ├── useCanvas.ts
│   │   │   ├── useSpotlight.ts
│   │   │   ├── useWebSocket.ts
│   │   │   └── useKubernetes.ts
│   │   ├── state/            # State management
│   │   │   ├── canvasStore.ts
│   │   │   ├── krateStore.ts
│   │   │   └── spotlightStore.ts
│   │   ├── utils/
│   │   │   ├── fuzzy.ts      # Fuzzy search algorithm
│   │   │   ├── crdt.ts       # Yjs setup
│   │   │   ├── keyboard.ts   # Keyboard handling
│   │   │   └── math.ts       # Canvas math helpers
│   │   ├── App.tsx
│   │   └── main.tsx
│   ├── public/               # Static assets
│   └── package.json
│
├── server/                    # Backend service
│   ├── cmd/
│   │   └── server/
│   │       └── main.go
│   ├── internal/
│   │   ├── api/             # HTTP endpoints
│   │   │   ├── handlers/
│   │   │   └── routes.go
│   │   ├── ws/              # WebSocket handlers
│   │   │   ├── shell.go
│   │   │   ├── logs.go
│   │   │   └── watch.go
│   │   ├── k8s/             # Kubernetes client wrappers
│   │   │   ├── client.go
│   │   │   ├── resources.go
│   │   │   └── watch.go
│   │   ├── crdt/            # Yjs integration
│   │   │   └── provider.go
│   │   └── auth/            # Authentication/authorization
│   │       └── token.go
│   ├── pkg/                 # Reusable packages
│   └── go.mod
│
├── design/                   # This folder
│   ├── canvas.md
│   ├── spotlight.md
│   ├── krate.md
│   ├── detail-window.md
│   ├── top-bar.md
│   ├── admin-drawer.md
│   ├── minimap.md
│   ├── backend.md
│   └── architecture.md
│
└── README.md

State Management Strategy

Global State (Zustand)

// canvasStore.ts
interface CanvasState {
  camX: number;
  camY: number;
  zoom: number;
  flying: boolean;
  dragging: boolean;
  collapsed: boolean;
  spacePanning: boolean;
}

// krateStore.ts
interface KrateStore {
  krates: Map<string, Krate>;
  selectedKrateId: string | null;
}

// spotlightStore.ts
interface SpotlightStore {
  open: boolean;
  query: string;
  filterType: string | null;
  sel: number;
  navigated: boolean;
}

// userStore.ts
interface UserStore {
  currentUser: User;
  presence: Map<string, UserPresence>;
}

Collection State (Per-Window)

// stored in krate.windows[].state or separate map
interface CollectionState {
  search: string;
  view: 'list' | 'tree';
  sel: number;
}

WebSocket Architecture

Connection Setup

1. Connect to /ws/sync (CRDT + awareness)
2. Connect to /ws/watch (resource updates)
3. On-demand connections:
   - /ws/shell (when shell window opened)
   - /ws/logs (when logs window opened)

Message Format

// CRDT sync
{
  type: 'sync',
  payload: Uint8Array  // Yjs update encoded
}

// Awareness presence
{
  type: 'awareness',
  updates: UserPresence[]
}

// Resource watch
{
  type: 'resource',
  action: 'add' | 'update' | 'delete',
  kind: string,         // 'Pod', 'Deployment', etc.
  resource: K8sObject
}

// Shell output
{
  type: 'shell:output',
  data: string          // stdout/stderr
}

// Shell input
{
  type: 'shell:input',
  data: string          // keypresses, etc.
}

Build & Deployment

Development

# Frontend
cd client
npm install
npm run dev  # Vite dev server

# Backend
cd server
go run cmd/server/main.go

Production

# Backend
cd server
go build -o krates-server
./krates-server --config config.yaml

# Frontend
cd client
npm run build
# Serve static files with nginx or similar

Docker

# Backend Dockerfile
FROM golang:1.21-alpine
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /krates ./cmd/server
CMD ["/krates"]

# Frontend Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
CMD ["npm", "start"]

Performance Optimization

Frontend

  1. Virtualization: Don't render off-screen krates if world is large
  2. Debounce: 16ms debouncing on all frequent events
  3. Web Workers: Fuzzy search in worker for large datasets
  4. Memoization: Reuse expensive calculations (transforms, layouts)
  5. CSS optimization: Use transforms, avoid layout thrashing

Backend

  1. Caching: Cache static resource lists (with watch for updates)
  2. Connection pooling: Reuse k8s API connections
  3. Rate limiting: Per-user limits on WebSocket connections
  4. Compression: WebSocket message compression
  5. Batching: Batch resource updates when possible

Testing Strategy

Unit Tests

  • Fuzzy search algorithm
  • Coordinate transformations
  • CRDT conflict resolution
  • WebSocket message formatting

Integration Tests

  • Kubernetes API integration
  • WebSocket connection lifecycle
  • Multi-user presence sync

E2E Tests

  • User flows: search → spotlight → krate creation
  • Multi-user: user A creates krate, user B sees it
  • Drag/drop and resize interactions

Security Checklist

Authentication

  • JWT or session-based auth on all WebSocket connections
  • Token validation on every message
  • Expire inactive sessions

Authorization

  • Namespace-level RBAC enforcement
  • Block access to unauthorized resources
  • Audit logging

Data Protection

  • Never log sensitive data (especially decoded secrets)
  • Sanitize user inputs
  • Escape HTML in text display
  • CSP headers on frontend

Network

  • TLS/HTTPS for all connections
  • WSS for WebSocket connections
  • Origin validation on WebSocket upgrade

Future Enhancements (Backlog)

Already Identified

  • Tile layout presets (logs hero, split, grid)
  • Port-forwarding window
  • Events window
  • Diff view (compare YAMLs)
  • Multi-cluster support

Additional Ideas

  • Keyboard shortcuts customization
  • Workspace presets (save/restore layouts)
  • Annotations/markers on canvas
  • Shared annotations (multi-user notes)
  • History/undo stack
  • Keyboard macro recording
  • Export workspace (screenshots, layouts)