The GitLeap terminal user interface (TUI) and accompanying asset generators require a unified visual identity across multiple target platforms. The user experience depends on distinct branding constraints, including a "one gradient" rule (restricting gradient transitions strictly to wordmark sheens and progress bars) and immediate responsiveness to focus/diagnostic changes.
Historically, UI styling and animation logic were tightly coupled to the component rendering layer through React/Ink primitives (like ). This design creates structural conflicts when porting core logic to alternative terminal engines, isolates long-running Map-Reduce event pipelines from synchronous React hook execution cycles, and risks unexpected performance drops or memory footprints inside a compiled command-line binary.
We need a deterministic approach to handle design tokens, color interpolation, cell-based sheen animations, and scroll calculations without introducing framework-specific side effects. Furthermore, we must permanently resolve the framework overlap between React/Ink and Rezi by choosing a single rendering engine.
By selecting this architecture, we are explicitly deprecating and purging all instances of React/Ink from the GitLeap codebase. Standardizing on Rezi allows the interface to operate as a direct canvas model. The headless global subsystem isolates layout math from layout processing loops. The presentation layers only need to consume these stateless engines and pass the generated output byte-streams directly down to Rezi cell buffers.
Houses the plain-data schema maps and frame-agnostic color math. This module has zero component dependencies.
typescript
/**
* GitLeap Design Tokens - Core Visual Language (Plain Data Engine)
* Framework-Agnostic, Zero-Dependency TUI Configuration
*/
export const COLOR = {
// Brand Primitives (The "Leap")
accent: '#00E5A3', // Transmuter Cyan (The Leap Forward / Success State)
primary: '#7C3AED', // Pipeline Purple (Git/AI Integration Space)
// Interface Typography & Canvas States
textNormal: '#F8FAFC', // Token Text (Crisp white for long readouts)
textMuted: '#64748B', // Diminished text noise (Paths, hashes, metrics)
bgCanvas: '#0B0F19', // Deep Terminal Canvas (Background base)
// Diagnostic State Flags
good: '#00E5A3', // Success / Greenlit / Pristine Primitive
warn: '#F59E0B', // Worker Warning / Cache Miss / AST Self-Correction Loop
bad: '#EF4444', // Compile Error / Malicious Injection Blocked
} as const;
export const ICON = {
success: '✓',
prompt: '❯',
pause: '⏸',
spinner: '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏', // Braille frame array sequence
folder: '📂',
primitive: '🔹',
manifest: '⚙',
guide: '📝',
package: '📦',
} as const;
export const RULE = {
borderFocused: COLOR.accent, // Focus-aware active layout panel border
borderUnfocused: '#1E293B', // Muted Slicing Gray for layout segmentation
dividerHorizontal: '#1E293B', // Trivial rule separator
} as const;
export const GUTTER = {
paddingLeft: 2,
paddingRight: 2,
} as const;
export const SOURCE_STYLE = {
agents: { tag: 'AGENT', hex: COLOR.primary },
skills: { tag: 'SKILL', hex: COLOR.accent },
manifests: { tag: 'JSON', hex: '#F59E0B' },
tests: { tag: 'TEST', hex: '#38BDF8' },
} as const;
function hexToRgb(hex: string): { r: number; g: number; b: number } {
const sanitized = hex.replace(/^#/, '');
const num = parseInt(sanitized, 16);
return {
r: (num >> 16) & 255,
g: (num >> 8) & 255,
b: num & 255,
};
}
function rgbToHex(r: number, g: number, b: number): string {
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
}
/**
* Pure hex color linear interpolation (lerp) helper.
* Computes intermediate hexadecimal colors for granular UI gradient ramps.
*/
export function lerpHex(fromHex: string, toHex: string, alpha: number): string {
const clampedAlpha = Math.max(0, Math.min(1, alpha));
const start = hexToRgb(fromHex);
const end = hexToRgb(toHex);
const r = Math.round(start.r + (end.r - start.r) * clampedAlpha);
const g = Math.round(start.g + (end.g - start.g) * clampedAlpha);
const b = Math.round(start.b + (end.b - start.b) * clampedAlpha);
return rgbToHex(r, g, b);
}
Use code with caution.
### 2. Sheen Animation Mathematical Engine (sheen.ts)
Enforces the "one gradient" constraint via a stateless 1D cosine-bell sweep over cell indices, mapping identically onto active progress components and SVG string outputs.
typescript
/**
* GitLeap Brand Animation Primitives - The "One Gradient" Rule Engine
* Shared deterministic module mapping a 1D cosine-bell sweep over cell matrices.
*/
export const SHEEN_CONFIG = {
SHEEN_PEAK: 1.0, // Absolute peak luminescent intensity multiplier
SHEEN_RADIUS: 6.0, // Total radius range of the gradient bell sweep across adjacent cells
SHEEN_TICK_MS: 50, // Fixed ticker loop processing step timing
SHEEN_SPEED: 0.4, // Progression step distance velocity per tick interval
SHEEN_MAX: 100, // Total logical period normalization ceiling boundary
} as const;
export interface SheenState {
sheenPeriod: number;
sheenCenter: number;
sheenIntensity: number;
}
/**
* Computes the spatial location vectors for a single sheen tick iteration loop.
*/
export function calculateSheenStep(tickCounter: number, totalWidth: number): SheenState {
const normalizedPeriod = SHEEN_CONFIG.SHEEN_MAX;
const currentStep = (tickCounter * SHEEN_CONFIG.SHEEN_SPEED) % normalizedPeriod;
const centerPosition = (currentStep / normalizedPeriod) * (totalWidth + SHEEN_CONFIG.SHEEN_RADIUS * 2) - SHEEN_CONFIG.SHEEN_RADIUS;
return {
sheenPeriod: normalizedPeriod,
sheenCenter: centerPosition,
sheenIntensity: SHEEN_CONFIG.SHEEN_PEAK,
};
}
/**
* Evaluates the precise intensity modifier for an individual text-cell position index.
* Equation: 0.5 * (1 + cos(pi * distance / radius))
*/
export function getCellSheenFactor(cellIndex: number, sheenCenter: number): number {
const distance = Math.abs(cellIndex - sheenCenter);
if (distance >= SHEEN_CONFIG.SHEEN_RADIUS) {
return 0;
}
const normalizedDistance = distance / SHEEN_CONFIG.SHEEN_RADIUS;
const bellFactor = 0.5 * (1 + Math.cos(Math.PI * normalizedDistance));
return bellFactor * SHEEN_CONFIG.SHEEN_PEAK;
}
export function applySheenToColor(baseHex: string, highlightHex: string, sheenFactor: number): string {
return lerpHex(baseHex, highlightHex, sheenFactor);
}
Use code with caution.
### 3. List Navigation & Window Math (move.ts)
Decoupled layout calculation algorithms that calculate scrolling adjustments independently of screen size or rendering mechanics.
typescript
/**
* GitLeap Pure UI Utilities - Scroll Window and Cursor Processing Math
* Framework-agnostic navigation layers with zero rendering bindings.
*/
/**
* Circular navigation array cursor calculation.
*/
export function wrapStep(currentIndex: number, stepDirection: -1 | 1, totalLength: number): number {
if (totalLength <= 0) return 0;
const nextIndex = currentIndex + stepDirection;
return (nextIndex + totalLength) % totalLength;
}
/**
* Computes a sliding window viewport starting index offset point.
* Ensures the selected list cursor element remains dynamically centered inside a viewport pane.
*/
export function windowStart(
currentIndex: number,
currentWindowStart: number,
viewportHeight: number,
totalLength: number
): number {
if (totalLength <= viewportHeight) {
return 0;
}
if (currentIndex < currentWindowStart) {
return currentIndex;
}
if (currentIndex >= currentWindowStart + viewportHeight) {
return currentIndex - viewportHeight + 1;
}
return currentWindowStart;
}
Context and Problem Statement
The GitLeap terminal user interface (TUI) and accompanying asset generators require a unified visual identity across multiple target platforms. The user experience depends on distinct branding constraints, including a "one gradient" rule (restricting gradient transitions strictly to wordmark sheens and progress bars) and immediate responsiveness to focus/diagnostic changes.
Historically, UI styling and animation logic were tightly coupled to the component rendering layer through React/Ink primitives (like ). This design creates structural conflicts when porting core logic to alternative terminal engines, isolates long-running Map-Reduce event pipelines from synchronous React hook execution cycles, and risks unexpected performance drops or memory footprints inside a compiled command-line binary.
We need a deterministic approach to handle design tokens, color interpolation, cell-based sheen animations, and scroll calculations without introducing framework-specific side effects. Furthermore, we must permanently resolve the framework overlap between React/Ink and Rezi by choosing a single rendering engine.
Decision Drivers
Considered Options
Decision Outcome
Chosen Option: Option 2: Headless Global Subsystem with Native Rezi Rendering.
By selecting this architecture, we are explicitly deprecating and purging all instances of React/Ink from the GitLeap codebase. Standardizing on Rezi allows the interface to operate as a direct canvas model. The headless global subsystem isolates layout math from layout processing loops. The presentation layers only need to consume these stateless engines and pass the generated output byte-streams directly down to Rezi cell buffers.
Architecture Specification & Modules
1. Design Tokens Engine (theme.ts)
Houses the plain-data schema maps and frame-agnostic color math. This module has zero component dependencies.