Files
opencode-krates-connector/design/collection-window.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

244 lines
6.9 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.
# Collection Window Feature Specification
## Overview
A collection window provides an overview of Kubernetes objects in a category (All Pods, All Services, etc.) or namespace. It supports both list and tree views with filtering and selection.
## Default Size
- Width: 540px
- Height: 480px (larger than detail windows for better data visibility)
## Header
### Title
- Format: `pods · ns/payments` or `All Pods`
- Bold styling
### Status Summary
- Health badges: `✓ N / ⚠ N / ✗ N`
- Colors: OK=green, Warn=amber, Error=red
- Order: Ready/Warn/Error counts
### Filter Input
- Auto-focused on open
- Styling:
- `font-family: IBM Plex Mono`
- `font-size: 12px`
- Placeholder: `Filter...`
- Instant filtering (no debounce needed for <1000 items)
### View Toggle
- **List mode** button: `list icon`
- **Tree mode** button: `tree icon`
- Toggles between list and tree display
- Keyboard shortcut: `t` or click toggle button
### Keyboard Hint
- Always visible, muted text: `↑↓ ⌥L/S/D/Y`
- Shows navigation + view shortcuts
## List Mode
### Row Structure
Each row displays:
- Shape glyph (8px, color-coded by object type)
- Name (primary text)
- Relation tag (muted, for tree mode)
- Health metric (icon or text)
- Type badge (small, muted)
- View buttons: `⌥L`, `⌥S`, `⌥D`, `⌥Y` (hover show tooltips)
- Status dot (green/amber/red)
### Selection
- Selected row:
- Background: `accentDim` (subtle accent color)
- Left border: `2px solid accent`
- Hover row:
- Background: `rgba(255,255,255,.04)`
- Border-radius: 4px
### Sorting
1. Primary: Health status
- Degraded/failed first
- Then pending
- Then ready/running
2. Secondary: Alphabetical within each group
## Tree Mode (k9s xray-style)
### Hierarchy
- **Workloads expand to pods**:
- Deployment → pods
- StatefulSet → pods
- DaemonSet → pods
- **Pods expand to resources**:
- Pods show configMaps, secrets, PVCs
- **Services/Ingresses expand to targets**:
- Show selectors
- Show endpoints
### Relation Tags
Show as small icons or labels:
- `pod` (attached to pod rows)
- `configMap` (mounted volumes)
- `secret` (mounted secrets)
- `volume` (PVC)
- `selects` (service → pods)
- `routes` (ingress → service)
- `used by` (reverse relationships)
### Indentation
- Per depth: `20px` indentation
- Connector: L-shaped border element (vertical + horizontal)
- Visual hierarchy clear at a glance
### Expand/Collapse
- Click chevron/arrow: Toggle children
- Double-click name: Toggle
- Click anywhere else on row: Select row
### Filtering in Tree Mode
- Matching nodes + **all their ancestors** must stay visible
- Ancestors shown even if not matching, but with different styling
- Children hidden if no match
- Preserves hierarchy readability
## Keyboard Navigation
### List/Tree Mode
| Key | Context | Action |
|---|---|---|
| ↑ / ↓ | Collection focused | Move row selection |
| PageUp / PageDown | Collection focused | Move selection by page |
| Home / End | Collection focused | First / last row |
| Enter | Row selected | Open default view for selected row |
| ⌥L / ⌥S / ⌥D / ⌥Y | Row selected | Open view for selected row |
| Esc | Filter focused | Blur filter input |
| Esc | Collection focused | No-op (handle in krate) |
| t | Anywhere | Toggle list/tree view |
### Mouse + Type Routing
- Mouse-over collection window + type = focus filter input
- Similar to shell routing but for filter input
- Use `hoveredWindowId` ref to determine routing
## View Shortcuts
### Key Mapping (All use ⌥ Alt)
- `⌥L`: Open logs view (if supported)
- `⌥S`: Open shell view (if supported)
- `⌥D`: Open describe view
- `⌥Y`: Open YAML view
### Implementation
- Event listener with `event.code` for layout safety
- Open views in newly created krate (or existing if spotlight session)
- Shell tab disabled for non-exec types (opacity 0.45)
## View-Specific Content
### Logs View (Pods/Workloads Only)
- **Streaming**: WebSocket → `kubectl logs --follow`
- **Auto-scroll**: To bottom unless user scrolled up
- **Color coding**:
- ERROR: `#ef6f6f`
- WARN: `#e8b54a`
- INFO: `#b9c6d8`
- **Timestamps**: Optional toggle (hidden by default)
### Shell View (Pods Only)
- **Implementation**: xterm.js
- **Disabled**: For non-pod workloads, show disabled (muted)
- **Cursor**: Blinking block cursor
- **Key routing**: Route to shell when collected window hovered
### Describe View
- Human-readable object description
- All metadata sections
- Formatted for easy scanning
### YAML View
- Full object YAML
- **Secrets**: Decode data values
- Banner: `⊙ secret values auto-decoded`
- Monospace font, line numbers optional
## Filter Behavior
### Instant Filtering
- No debounce (fast for <1000 items)
- Debounce if dataset grows: 16ms
### Filter Logic
- Case-insensitive substring match
- Match against: name, labels, annotations, namespace
- For tree mode: Match name only (not ancestors)
### Clear Filter
- Esc key (when filter focused)
- Clear button (×) in input
- Empty string clears filter
### Keyboard Focus
1. Click collection window + type = focus filter
2. Click filter input = focus
3. Click anywhere else = blur filter, focus canvas shortcuts
## State Management
### Per-Window State
```typescript
interface CollectionState {
wid: string; // window ID
search: string; // filter text
view: 'list' | 'tree';
sel: number; // selected row index
expanded: Set<string>; // tree expansion state (node IDs)
}
```
### Data Loading
```typescript
interface CollectionData {
kind: string; // 'Pod', 'Service', etc.
namespace?: string; // undefined for "All Pods"
items: K8sObject[];
filtered: K8sObject[]; // after filter
treeData?: TreeNode[]; // tree mode intermediate
}
```
## Tree Node Structure
```typescript
interface TreeNode {
id: string; // unique within collection
name: string;
kind: string; // 'Pod', 'Deployment', etc.
obj: K8sObject | null; // null for synthetic nodes (e.g., "pods")
depth: number;
parentId: string | null;
children: string[]; // node IDs
relation: string; // 'pod', 'configMap', 'selects', etc.
hasChildren: boolean;
}
```
## Performance Considerations
### Large Datasets
- List virtualization: Only render visible rows (window height / row height)
- Tree optimization: Lazy expand (fetch children on expand, not preload)
- Filtering: Use efficient algorithms (no regex, simple string.match)
### Updates
- Throttle tree rebuild: 100ms
- Only rebuild if filter or data changed
- Keep expansion state on update (if node still exists)
## Gotchas
1. **Tree expansion**: Keep ancestors visible when filtering
2. **Auto-focus**: Focus filter input on window open (use ref + useEffect)
3. **View shortcuts**: Use `event.code` (layout-safe)
4. **Sorting priority**: Health first, then alphabetical
5. **Shell vs other types**: Disable shell tab for non-pod workloads
6. **Filter scope**: In tree mode, filter only on names, not on ancestors