Files
opencode-krates-connector/design/krate.md
Hermes Agent 89bc5e8c15 docs: Finalize all design documents
Signed-off-by: Hermes Agent <hermes@nosuchhost>
2026-06-16 09:00:33 -04:00

102 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design Document: Krate (Window Group) Feature Specification
## Overview
A krate is a named group of detail windows for a single Kubernetes object or collection. Krates live on the canvas and serve as organizational units for related workspace views.
## Core Responsibilities
- Group related windows together visually and logically
- Auto-fit frame around contained windows
- Manage window layout within krate boundaries
- Handle krate-level interactions (move, drag, collapse, expand)
## Visual Container
### Krate Frame
- **Dashed border**: `border: 1px dashed rgba(color, .3)`, `border-radius: 18px`
- **Background**: `rgba(color, .04)` (subtle color tint)
- **Auto-fit**: Frame adjusts to bounding box of all windows + 30px padding
- **Color**: Matches namespace palette (e.g., payments: `#6fb1ff`)
### Header Bar
Above the frame:
- Shows object name + status badge + window count
- **Drag handle**: Move entire krate
- **× button**: Dismiss krate
- **Minimize button** (`—`): Collapse to overview card
- **Double-click header**: Collapse/expand toggle
## Window Layout
### Grid System
- Windows tiled in 2-column grid
- Column 0: `dx: 0`
- Column 1: `dx: 412`
- Row height: 416px
- **Window default size**: 380×362px
### Properties
- Windows never overlap (snap-to-grid on release)
- When one window resized, siblings resize proportionally in same column/row
- Storage:
```typescript
interface Window {
wid: string;
kind: 'detail' | 'collection';
tab: 'logs' | 'shell' | 'describe' | 'yaml';
dx: number; // offset within krate (column * 412)
dy: number; // offset within krate (row * 416)
w: number;
h: number;
}
```
## Krate Interactions
### Dragging
- **Drag header** = move entire krate
- **Non-overlapping placement**: On drag release, nudge to avoid overlap with other krates
- **Gentle snap, not strict grid** (allows flexibility while preventing overlap)
### Collapse/Expand
- **Minimized state**: 230px-wide card showing:
- Name
- View-letter badges (Y/D/L/S)
- Status dot
- Window count
- Namespace
- **Double-click collapsed card**: Re-expand and fly camera to krate
### Camera Fly
- On krate creation: animate camera to center krate at `zoom: 0.92`
- Duration: `.52s cubic-bezier(.22,.8,.28,1)`
- Position: center of krate's bounding box
## Krate State
```typescript
interface Krate {
id: string;
objId: string | null; // null for collection krates
collScope?: { kind: 'namespace' | 'category', value: string };
label: string; // display name
status: string; // status badge text
color: string; // hex, from namespace palette
wx: number; wy: number; // world position (top-left of frame)
minimized: boolean;
windows: Window[];
seq: number; // for generating unique window IDs
}
```
## Non-Overlapping Placement Algorithm
1. Try computed default position
2. Check bounding boxes against all existing krates
3. If overlap, nudge by fixed increments (e.g., 20px right/down)
4. Repeat until no overlap
5. **Same algorithm** used on creation AND drag release
## Gotchas
1. **Auto-fit frame**: Re-compute bounding box whenever windows are added/removed/moved/resized
2. **Non-overlapping**: Use AABB (Axis-Aligned Bounding Box) collision detection
3. **Window grid**: Store `colWidths` and `rowHeights` arrays for proper resize relationships (future enhancement)
4. **Krate ID**: `objId` is null for collections; otherwise references the Kubernetes object ID