Quick Reference
Features Covered
| Feature | Module | Version |
|---|---|---|
| WebGL CRT Engine | desktop/src/engine/ | v1.18 |
| Calibration Wizard | desktop/src/calibration/ | v1.19 |
| Window Manager | desktop/src/wm/ | v1.20 |
| Desktop Shell | desktop/src/shell/ | v1.21 |
| Tauri Integration | desktop/src-tauri/ | v1.21 |
Prerequisites
- GS-1: Installation & Setup
- Rust toolchain (for Tauri backend compilation)
- Node.js 18+ with npm (for Vite frontend build)
- WebGL2-capable GPU (integrated graphics sufficient)
- Familiarity with Chipset Architecture concepts (recommended)
Configuration Reference
CRT shader settings:
// Stored in local config after calibration
{
"crt": {
"intensity": 0.7,
"scanline_density": 1.0,
"curvature": 0.3,
"bloom": 0.4,
"phosphor_glow": 0.5
}
}
Palette selection:
{
"palette": {
"preset": "amiga-wb-3.1",
"custom_anchors": null,
"mode": "dark"
}
}
Tauri window config:
// src-tauri/tauri.conf.json
{
"windows": [{
"title": "GSD-OS",
"width": 1280,
"height": 800,
"decorations": false,
"resizable": true
}]
}
Related Guides
Technical Specifications
| Rendering | WebGL2, multi-pass shader pipeline |
| Shader Passes | 3 (distortion, post-processing, palette background) |
| Color System | 32-color indexed palette, OKLCH generation |
| Palette Presets | 5 built-in (WB 1.3, WB 2.0, WB 3.1, C64, Fox) |
| Default Resolution | 1280x800 (decorationless window) |
| Target FPS | 60 (warning below 30) |
| Terminal | xterm.js + WebGL addon, full PTY |
| Backend | Tauri v2, Rust, portable-pty crate |
| Frontend | TypeScript, Vite, Zod validation |
| Copper List | Nx1 RGBA texture, GPU-driven backgrounds |
Related CAP References
Overview
GSD-OS is not a web application running in a browser tab. It is a native desktop application built with Tauri v2 — a Rust backend providing system-level access to file watching, pseudo-terminal sessions, native dialogs, and window management, paired with a TypeScript frontend that renders through a WebGL2 CRT shader pipeline. The result is a complete desktop environment where GSD planning dashboards, terminal sessions, Claude interactions, and skill management coexist as managed windows with Amiga Workbench-style chrome.
The visual design is a deliberate homage to the Commodore Amiga Workbench, the desktop environment of the Amiga line of personal computers produced from 1985 through the mid-1990s. The Amiga was revolutionary for its time: a multitasking operating system with a custom chipset providing dedicated hardware for graphics, sound, and I/O — at a price point accessible to home users. GSD-OS inherits the Amiga's visual language (titlebar gadgets, depth cycling, icon areas, the distinctive beveled window chrome) while adding modern capabilities: GPU-accelerated CRT shader effects, OKLCH color space calculations for palette generation, and a 32-color indexed palette system that honors the constraints of the original hardware while providing contemporary usability.
This guide covers the five subsystems that comprise the desktop environment: the WebGL CRT rendering engine that provides the visual foundation, the calibration wizard that configures the experience on first boot, the window manager that handles Amiga-style window operations, the desktop shell that ties everything together, and the Tauri integration layer that connects the frontend to native system capabilities.
GSD-OS is an optional component of the skill-creator ecosystem. Everything it provides (dashboard viewing, terminal sessions, Claude interaction) can also be done through the CLI and a web browser using serve-dashboard.mjs. The desktop application adds three things that the CLI cannot: the immersive retro visual environment, real-time file watching with automatic dashboard refresh, and a unified window management experience that keeps all project tools in one application. For developers who work in terminal multiplexers like tmux, GSD-OS provides a graphical complement rather than a replacement — it can even bind to existing tmux sessions.
Key Concepts
In the 1980s and early 1990s, the Commodore Amiga was the computer that creative professionals, musicians, and game developers used. It had something called a "custom chipset" — dedicated hardware chips named Agnus, Denise, and Paula that handled graphics, display, and sound independently from the main processor. This meant the Amiga could do things that other computers of its era simply could not: smooth animations, rich color palettes, and multitasking with multiple windows, all while running on modest hardware.
GSD-OS recreates this experience for a modern context. Instead of dedicated hardware chips, GSD-OS uses your computer's GPU (graphics processing unit) to render a CRT monitor effect — the scan lines, the slight screen curvature, the phosphor glow that made old monitors feel warm and alive. This is not just nostalgia. The Amiga's design philosophy — dedicated subsystems communicating through well-defined interfaces, constrained palettes that force visual clarity, a window manager that treats depth ordering as a first-class concept — turns out to be a remarkably effective metaphor for managing complex software projects.
Think of GSD-OS as a virtual desk. Each window is a piece of your project: one window shows your planning dashboard, another runs a terminal session, another manages your Claude AI conversation. You can arrange them, cycle their depth order (bringing background windows to the front with a single click), minimize them to icons, and navigate between them using keyboard shortcuts. The CRT shader makes the entire experience visually distinctive — your project management environment looks and feels different from your browser, your email, and everything else on your screen, which helps maintain focus.
For teachers: GSD-OS provides a self-contained environment for student projects. Students can see their project status (which phases are complete, what requirements are met) in the dashboard window, work in the terminal window, and manage their AI interactions — all in one place with consistent visual language. The retro aesthetic also creates a conversation starter about computing history and hardware architecture.
The 32-color palette is a teaching opportunity in itself. Graphic designers, game developers, and digital artists all work with color constraints. A 32-color palette forces deliberate choices about which colors to assign to which elements — exactly the kind of decision-making that builds strong design intuition. Students can experiment with custom palette generation to see how changing a single anchor color ripples through the entire UI, learning about color theory and perceptual uniformity through hands-on experimentation.
The window manager's depth cycling is also worth understanding as a computer science concept. Instead of a flat list of windows, GSD-OS maintains a stack (a z-order). Operations on this stack (push to front, send to back) are classic data structure operations that students encounter in computer science courses. The visual feedback of seeing windows cycle through the depth order makes this abstract concept tangible.
Why Amiga?
The choice of Amiga Workbench as the visual and architectural inspiration for GSD-OS is not arbitrary nostalgia. The Amiga's design philosophy maps directly to the problems that GSD-OS solves. The Amiga's custom chipset used dedicated hardware for each subsystem (Agnus for memory/DMA, Denise for display, Paula for audio/IO), communicating through well-defined bus interfaces. GSD-OS mirrors this with dedicated software subsystems (engine for rendering, wm for window management, shell for desktop chrome, dashboard for planning data), communicating through typed interfaces and event buses.
The Amiga's 32-color palette constraint forced developers to think carefully about visual hierarchy. With only 32 colors available, every color choice had to be intentional: which colors are for chrome (window borders, titlebar), which for content (text, backgrounds), which for status (selection highlights, error indicators). GSD-OS inherits this discipline. The 32-color indexed palette means that every UI element's color is assigned from a limited, curated set. Changing the palette preset instantly re-themes the entire application because every element references a palette index, not a hard-coded hex value.
Depth cycling — the Amiga's signature window management pattern — turns out to be more efficient than minimize-and-restore for multi-window workflows. When you have a terminal, a dashboard, and a Claude session open simultaneously, depth cycling lets you bring any window to the front with a single click on its depth gadget, without losing your spatial arrangement. Minimize-and-restore requires finding the minimized icon, double-clicking, and the window may reappear at a different size or position. Depth cycling preserves the entire window state.
The CRT aesthetic itself has a functional purpose beyond nostalgia: it creates a distinct visual context that separates the project management environment from everything else on the user's screen. When you are working in GSD-OS, the CRT shader and Amiga chrome create an unmistakable visual boundary. This context switching cue is similar to how some developers use different terminal color schemes for different environments (production vs. staging) — the visual difference triggers a mindset shift. GSD-OS takes this principle to the extreme with a full retro desktop environment that is impossible to confuse with your regular operating system.
How It Works
Boot Sequence
When GSD-OS launches, it runs a boot sequence (desktop/src/boot/) that initializes each subsystem in order. The boot sequence is both functional (it actually initializes the WebGL context, loads palettes, starts the window manager) and theatrical (it displays an Amiga-style boot screen with chipset names scrolling past, mimicking the Amiga's power-on memory check and hardware detection). The boot screen renders through the CRT shader from the very first frame, establishing the visual identity immediately.
The boot sequence progresses through these stages: WebGL context creation, shader compilation and linking, palette texture upload, copper list initialization, window manager startup, shell chrome rendering, file watcher initialization, and finally desktop display. If the calibration wizard has not been run (first boot), it launches after the boot sequence completes. Subsequent boots skip the wizard and proceed directly to the desktop.
The boot animation takes approximately 2-3 seconds. It cannot be skipped on the first launch (the initialization is genuinely happening during the animation), but subsequent launches can be configured to skip the animation and show the desktop immediately by setting "skip_boot_animation": true in the local config.
The chipset names displayed during boot (Agnus, Denise, Paula, Gary, Buster) are not just decorative — they correspond to actual software subsystems in the GSD-OS architecture. Agnus handles memory management and DMA scheduling (in GSD-OS: the IPC message bus and data pipeline). Denise handles display generation (the WebGL engine and shader pipeline). Paula handles audio and I/O (the PTY terminal and file watcher). Gary handles address decoding and routing (the GSD orchestrator). Buster handles bus arbitration and expansion (the plugin and extension system). This naming convention is documented in the Chipset Architecture guide.
# Boot sequence output (typical):
[GSD-OS Boot v1.21]
Checking Agnus... DMA controller initialized
Checking Denise... WebGL2 context created (NVIDIA GeForce RTX)
Shader: crt-distort.frag compiled OK
Shader: crt-post.frag compiled OK
Shader: palette-bg.frag compiled OK
Checking Paula... PTY subsystem ready
File watcher: monitoring .planning/
Checking Gary... Orchestrator loaded (25 commands registered)
Checking Buster... Extension bus ready
Memory: 1280x800 framebuffer allocated
Palette: Amiga Workbench 3.1 MagicWB (32 colors)
Copper: gradient program loaded (256 scanlines)
Desktop ready.
WebGL CRT Engine
The WebGL CRT Engine (desktop/src/engine/, introduced in v1.18) is the visual foundation of GSD-OS. Every pixel rendered in the desktop environment passes through a multi-pass GPU shader pipeline that simulates the characteristics of a CRT (cathode ray tube) monitor. The engine runs in a WebGL2 canvas that covers the entire application window, compositing all UI elements — windows, icons, taskbar, desktop background — through the shader chain before final display.
The shader pipeline consists of three passes executed on the GPU every frame. The CRT distortion pass (shaders/crt-distort.frag) applies barrel distortion and vignetting to simulate the physical curvature of a CRT screen. Barrel distortion bows the image outward at the edges, exactly as a real curved CRT screen would distort a flat image. Vignetting darkens the corners, simulating the reduced electron beam intensity at the screen periphery. Both effects are parameterized: curvature ranges from 0.0 (flat) to 1.0 (heavily curved), and vignette intensity is independently controllable.
The CRT post-processing pass (shaders/crt-post.frag) adds the characteristic visual artifacts that distinguish CRT displays from modern flat panels. Scan lines — the horizontal gaps between electron beam passes — are rendered as alternating bright and dark horizontal bands with configurable density and intensity. Phosphor glow simulates the light emission from phosphor coating on the CRT's inner surface, creating a soft bloom effect around bright elements. Color fringing shifts the red, green, and blue channels by a sub-pixel offset, simulating the misalignment of electron guns in a shadow mask CRT.
The palette background pass (shaders/palette-bg.frag) renders the desktop background using palette-indexed colors driven by the copper list system. Rather than displaying a static image, the background is generated procedurally from a program that specifies per-scanline color indices with interpolation — producing gradient effects, raster bars, and animated backgrounds at GPU speed with zero CPU overhead per frame. This directly mirrors how the Amiga's Copper coprocessor could change display registers on each scanline to produce color cycling and gradient effects.
# CRT shader parameters (all configurable via calibration wizard)
Curvature: 0.0 (flat) to 1.0 (maximum barrel distortion)
Scanline density: 0.5 (subtle) to 2.0 (heavy)
Bloom: 0.0 (none) to 1.0 (maximum phosphor glow)
Phosphor glow: 0.0 (none) to 1.0 (maximum per-pixel bloom)
Color fringe: 0.0 (none) to 1.0 (maximum RGB channel offset)
Vignette: 0.0 (none) to 1.0 (heavy corner darkening)
# Disable CRT effects entirely for a clean display:
# Set all values to 0.0 in the calibration wizard
# The Amiga-style UI chrome remains; only the CRT filter is removed
# Performance impact of each parameter (approximate):
# Curvature: Low (simple UV remapping)
# Scanlines: Low (per-pixel modulation)
# Bloom: High (multi-pass Gaussian blur)
# Phosphor: Medium (per-pixel luminance computation)
# Color fringe: Low (RGB channel offset)
# Vignette: Low (distance-from-center computation)
Calibration Wizard
The Calibration Wizard (desktop/src/calibration/, introduced in v1.19) is the first experience when launching GSD-OS for the first time. It walks the user through three screens of configuration to ensure the visual experience is optimal before regular use begins. The wizard stores all preferences in local config and can be re-launched at any time from the system menu.
The first screen is CRT Settings Adjustment. The user sees a live preview of the desktop with the CRT shader applied, alongside sliders for curvature, scanline density, bloom, phosphor glow, and color fringe. As sliders are adjusted, the preview updates in real time. This is where users who prefer a clean, modern display can reduce all CRT effects to zero, retaining the Amiga-style window chrome and palette without the CRT visual treatment. A "Recommended" preset provides a balanced starting point that looks good on most modern displays.
The second screen is Color Palette Selection. GSD-OS uses a 32-color indexed palette system — a deliberate constraint inspired by the Amiga's hardware palette limitations. The wizard presents five built-in presets: Amiga Workbench 1.3 (the classic blue, white, black, and orange four-color scheme), Amiga Workbench 2.0 (the gray-based eight-color palette with colored accents), Amiga Workbench 3.1 MagicWB (a full 32-color UI chrome palette), Commodore 64 (the canonical 16 colors with 16 variations), and a custom default palette designed for the fox watercolor identity of the project. Users can also generate a custom palette by selecting anchor colors — the system uses OKLCH color space calculations to produce a harmonious 32-color set with controlled lightness, chroma, and hue distribution from just two or three anchor inputs.
The third screen handles Theme Mode and Accessibility. Theme mode selection offers light, dark, and auto (follows system preference). The wizard also runs basic accessibility detection: it checks for reduced-motion preferences (disabling CRT animation effects), high-contrast mode preferences (boosting palette contrast), and screen reader compatibility settings. These settings are stored alongside the palette and CRT configuration and can be changed independently later.
The OKLCH color space used for custom palette generation deserves explanation. OKLCH stands for OK Lightness Chroma Hue — a perceptually uniform color space where equal numeric changes produce equal perceived visual differences. This is critical for generating harmonious palettes: in RGB or HSL, selecting evenly-spaced hue values produces palettes that look uneven (some hues appear brighter or more saturated than others). In OKLCH, the algorithm can control perceived lightness independently from hue, ensuring that all 32 colors in the palette have the intended visual weight regardless of their hue. The culori library handles the OKLCH math, and the result is palettes that look professionally designed from just two or three anchor color inputs.
All calibration settings are persisted to the local application data directory and loaded on subsequent launches. The settings are stored as a JSON file that can be manually edited for fine-grained control beyond what the wizard offers. The calibration wizard can be re-launched at any time from the system menu without losing the current desktop session — changes are applied live as you adjust sliders.
# Re-launch calibration wizard from the system menu:
# System Menu > Settings > Recalibrate Display
# Built-in palette presets:
1. Amiga Workbench 1.3 — 4 colors: blue, white, black, orange
2. Amiga Workbench 2.0 — 8 colors: grays + colored accents
3. Amiga Workbench 3.1 — 32 colors: full MagicWB chrome
4. Commodore 64 — 16+16 colors: canonical C64 palette
5. Fox Default — 32 colors: burnt orange, amber, cream, charcoal
# Generate custom palette from anchor colors:
# Select 2-3 anchor colors in the picker
# OKLCH algorithm generates remaining 29-30 colors
# Preview applies immediately to all UI elements
Window Manager
The Window Manager (desktop/src/wm/, introduced in v1.20) implements Amiga-style window management with the distinctive interaction patterns that set the Amiga Workbench apart from contemporaries like Windows 3.1 or Mac System 7. On the Amiga, windows were not just rectangular areas with close buttons — they were layered objects with dedicated hardware support for depth ordering, and the UI reflected this through titlebar gadgets that made depth cycling a first-class operation.
Every window in GSD-OS has a titlebar with four gadgets, following the original Amiga convention. The close gadget (top-left) closes the window. The depth gadget (top-right, two overlapping rectangles) cycles the window's depth position: clicking it sends a front window to the back, or brings a back window to the front. This is the Amiga's signature interaction — rather than a "minimize" button, you cycle depth. The resize gadget (bottom-right corner) allows proportional or free-form resizing by dragging. The zoom gadget (top-right, next to depth) toggles between the window's current size and its maximum size, functioning like a maximize toggle.
Window drag is handled through drag regions — the titlebar area between the close gadget and the depth/zoom gadgets. Clicking and dragging in this region moves the window. The window manager enforces screen boundaries: windows cannot be dragged completely off-screen, though they can be partially hidden by dragging them to the edge.
Depth ordering is managed as a z-order stack. Every window has a z-index, and the window manager maintains the stack invariant: no two windows share the same z-index. When a window is clicked (anywhere, not just the titlebar), it moves to the front of the stack. The depth gadget provides explicit control: clicking it on the frontmost window sends it to the back, and clicking it on any other window brings it to the front. This cycling behavior lets users rapidly switch between overlapping windows without needing to move or resize them.
The icon area occupies the bottom portion of the desktop. When a window is minimized (via the close gadget with a modifier key, or through the system menu), it collapses to an icon in the icon area. Double-clicking the icon restores the window to its previous size and position. Icons in the area can be rearranged by dragging, and they auto-arrange to avoid overlapping.
The window manager also handles window snapping as a modern convenience not present in the original Amiga. Dragging a window to the left or right screen edge snaps it to half-screen width. Dragging to a corner snaps to quarter-screen. This hybrid approach — Amiga visual language with modern productivity features — reflects GSD-OS's design philosophy: honor the retro aesthetic without sacrificing contemporary usability.
All window positions and sizes are tracked in a window state store. When a window is closed and reopened (e.g., closing and re-opening the Dashboard), it appears at its previous position and size. This state persists across application restarts (stored in the local config alongside calibration settings). The window state store also enables "workspace save/restore" — the ability to save a complete window arrangement and restore it later, which is useful for switching between different project contexts.
A subtlety of the depth ordering system: unlike modern desktop operating systems where clicking any part of a window brings it entirely to the front, GSD-OS offers more granular control. Clicking within a window's content area brings it to the front (matching modern expectations). But clicking the depth gadget toggles the window between front and back, which is the Amiga-specific behavior. This means the depth gadget is predictable: click it on any window, and you know exactly what will happen. Front goes to back, back goes to front. This deterministic behavior reduces cognitive load compared to ambiguous "bring to front" semantics where users must remember the current z-order to predict the result.
# Window manager keyboard shortcuts:
Ctrl+W Close active window
Ctrl+Shift+D Cycle active window depth (front/back)
Ctrl+Shift+M Minimize active window to icon area
Ctrl+Shift+Z Toggle zoom (maximize/restore)
Alt+Drag Move window from any point (not just titlebar)
Ctrl+Tab Cycle focus to next window in z-order
Ctrl+Shift+Tab Cycle focus to previous window in z-order
# Window types in GSD-OS:
- Terminal window (PTY session, xterm.js rendering)
- Dashboard window (planning dashboard HTML view)
- Claude window (Claude session interaction)
- Settings window (calibration, preferences)
- Process monitor (system resource tracking)
Desktop Shell
The Desktop Shell (desktop/src/shell/, introduced in v1.21) is the top-level environment that ties together the window manager, icon system, taskbar, and system menu into a complete desktop experience. If the window manager is the skeleton, the shell is the skin: it provides the visual surface and interaction patterns that users see and touch.
The desktop icons system provides direct access to core GSD-OS functions. Each icon is registered in the icon registry (desktop/src/shell/icon-registry.ts) with a name, image, associated action, and position. Default icons include Terminal (opens a new PTY session), Dashboard (opens the planning dashboard), Claude (starts a Claude session), and Disk (opens the file browser). Users can create custom icons for frequently-used operations. Icons follow the Amiga convention of small, pixel-art-styled graphics that are legible at the 32-color palette constraint.
The taskbar runs along the bottom of the screen (configurable to top), showing all open windows as labeled buttons. Clicking a taskbar button brings the corresponding window to the front. The taskbar also displays the system clock, the active palette name, and status indicators for file watcher activity and Claude session health. The taskbar inherits palette styling and renders through the CRT shader, maintaining visual consistency with the rest of the desktop.
The system menu is accessed from the top-left corner of the screen (or via a configurable keyboard shortcut). It provides hierarchical access to all GSD-OS functions: New Terminal, New Dashboard, New Claude Session, Settings (launching the calibration wizard), About, and Quit. The menu also includes a "GSD" submenu that lists available GSD slash commands, providing a point-and-click alternative to typing commands in the terminal.
Keyboard navigation is comprehensive. Every function accessible via mouse is also accessible via keyboard. The shell implements a focus ring system that tracks which element has keyboard focus (window, icon, taskbar button, or menu item) and provides visible focus indicators styled with the active palette. Tab cycles focus between top-level areas (desktop, taskbar, active window), and arrow keys navigate within each area.
The process monitor (desktop/src/shell/process-monitor.ts) tracks resource consumption of active GSD-OS components: PTY sessions, Claude sessions, file watcher events, and rendering performance (FPS, GPU memory). It is accessible from the system menu and opens as a standard managed window. This is particularly useful for diagnosing performance issues — if the CRT shader is consuming excessive GPU resources on older hardware, the process monitor will show the frame time breakdown.
tmux Integration
GSD-OS can bind to existing tmux sessions through the tmux module (desktop/src/tmux/). When tmux is detected on the system, the terminal window offers the option to attach to an existing tmux session rather than starting a new shell. This is particularly valuable for long-running GSD workflows: if a phase execution is running in tmux and GSD-OS is restarted (for updates or crash recovery), the terminal window can reattach to the running session without interrupting the execution.
The tmux bridge (desktop/src/tmux/bridge.ts) communicates with the Rust backend's tmux detection module to list available sessions, create new sessions, and attach to existing ones. When attached to a tmux session, the terminal window displays the tmux status bar at the bottom (within the window content area, below the xterm.js terminal), and tmux keyboard shortcuts work normally. The window manager's depth cycling and the tmux session management operate independently — cycling the terminal window's depth does not affect the tmux session, and switching tmux windows does not change the GSD-OS window state.
Claude Session Windows
The Claude session module (desktop/src/claude/) provides a dedicated window type for Claude Code interactions. Unlike the terminal window (which is a general-purpose shell where Claude can be invoked), the Claude window is specifically designed for Claude session management. It displays the session's health status (active, idle, error), token consumption (context window usage), and provides controls for starting, stopping, and restarting sessions.
The Claude session monitor (desktop/src/claude/monitor.ts) tracks session health in the background. If a Claude session becomes unresponsive or encounters an error, the monitor displays a notification in the taskbar and the Claude window's titlebar gadgets change to indicate the error state (a visual cue borrowed from the Amiga's disk activity indicator). The monitor also tracks cumulative token usage across sessions, providing insight into how much context window capacity is being consumed during a GSD workflow.
# Desktop shell keyboard shortcuts:
F1 Open system menu
F2 Quick-launch terminal
F3 Quick-launch dashboard
F5 Refresh active dashboard
Tab Cycle focus: desktop > taskbar > active window
Escape Close menu / deselect icon
Arrow keys Navigate within focused area
Enter/Space Activate focused element
Ctrl+Q Quit GSD-OS
# Process monitor metrics:
FPS: Target 60fps, warning below 30fps
GPU Memory: WebGL buffer allocation tracking
PTY Sessions: Count and data throughput
Claude Sessions: Active sessions and token consumption
File Watcher: Event count and debounce status
Tauri Integration
The Tauri Integration layer (desktop/src-tauri/, introduced in v1.21) is the bridge between the TypeScript frontend and the native operating system. Tauri v2 provides a Rust-based backend that exposes system capabilities to the web view through IPC (inter-process communication) commands. GSD-OS uses this to provide four critical capabilities that are impossible in a standard web application: file system access, pseudo-terminal sessions, native window management, and file watching.
IPC Commands are the primary communication mechanism between the frontend and backend. The frontend invokes Rust functions through Tauri's invoke API, and results are returned as JSON. GSD-OS exposes IPC commands for file system operations (reading and writing .planning/ files, listing directory contents), window management (setting window size, toggling fullscreen, controlling native decorations), native dialogs (file open/save, confirmation prompts), and application lifecycle (startup initialization, graceful shutdown). All IPC commands are defined in src-tauri/src/commands/ and registered in the Tauri application builder.
File Watcher (src-tauri/src/watcher.rs) monitors the .planning/ directory for changes using the notify crate with debounced events. When planning documents change — STATE.md is updated, a phase plan is created, ROADMAP.md is modified — the watcher emits events to the frontend via Tauri's event system. The frontend's dashboard module listens for these events and triggers dashboard regeneration, ensuring the visual display always reflects the current project state. Debouncing prevents event storms during bulk file operations (such as GSD creating an entire phase directory structure).
PTY Terminal (src-tauri/src/pty/) provides a full pseudo-terminal emulator backed by the portable-pty Rust crate. The PTY module manages the complete terminal session lifecycle: opening new sessions (with configurable shell), writing input from the frontend's xterm.js terminal, reading output and streaming it back to the frontend via Tauri events, handling resize events when the terminal window changes size, and managing session pause/resume/close. Flow control prevents buffer overflows when the frontend cannot render terminal output fast enough — the PTY module buffers output and delivers it in chunks that match the frontend's rendering capacity.
The frontend's terminal module (desktop/src/terminal/) uses xterm.js with the WebGL addon for hardware-accelerated terminal text rendering. The PTY bridge (desktop/src/terminal/pty-bridge.ts) connects xterm.js to the Rust PTY backend, translating keyboard events to PTY input and PTY output to xterm.js rendering commands. This produces a terminal that is indistinguishable in capability from a native terminal emulator — full ANSI escape code support, 256-color rendering, mouse event passthrough, and proper Unicode handling.
The Rust backend services extend beyond IPC commands to include thread-safe state management. The backend maintains Mutex-wrapped state objects for the application configuration, file watcher subscription list, PTY session pool, and Claude session manager. The Tauri configuration (tauri.conf.json) defines a single decorationless main window at 1280x800 — GSD-OS provides its own window chrome through the frontend's window manager, so native OS decorations are intentionally disabled to maintain the Amiga aesthetic.
The architecture of the Tauri integration is deliberately thin. The Rust backend does not contain business logic about GSD workflows, skill management, or dashboard content. It provides raw capabilities (file access, PTY, window control) and the frontend decides how to use them. This separation means the backend rarely needs updating when GSD features change — it is a stable foundation that the frequently-changing frontend builds upon.
Error handling in the IPC layer follows a consistent pattern: all IPC commands return Result<T, String> where the error string is a human-readable message. The frontend's IPC module wraps each invocation in a try/catch that displays errors as notification toasts in the taskbar area (styled with palette colors, rendered through the CRT shader like everything else). Critical errors (PTY failure, file system permission denied) also write to the diagnostic log for post-mortem analysis.
# Build GSD-OS from source:
cd desktop && npm install
cd src-tauri && cargo build
# Run in development mode (with hot reload):
cd desktop && npm run tauri dev
# Build production binary:
cd desktop && npm run tauri build
# Output: src-tauri/target/release/gsd-os
# IPC command examples (frontend TypeScript):
import { invoke } from '@tauri-apps/api/core';
// Read a planning file
const content = await invoke('read_file', {
path: '.planning/ROADMAP.md'
});
// Open a new PTY session
const sessionId = await invoke('pty_open', {
shell: '/bin/bash',
cols: 80,
rows: 24
});
// Write to PTY
await invoke('pty_write', {
sessionId,
data: 'skill-creator status\n'
});
// Listen for file watcher events
import { listen } from '@tauri-apps/api/event';
await listen('planning-changed', (event) => {
console.log('File changed:', event.payload);
regenerateDashboard();
});
Usage Examples
First Launch Experience
# 1. Launch GSD-OS
./gsd-os # or: cd desktop && npm run tauri dev
# 2. Boot sequence plays (chipset initialization animation)
[Amiga-style boot screen with memory check]
[Custom chipset names scroll: Agnus, Denise, Paula, Gary, Buster]
[Desktop background renders through copper list]
# 3. Calibration wizard launches (first boot only)
Screen 1: CRT Settings
- Curvature slider: 0.3 (moderate)
- Scanlines: 1.0 (standard)
- Bloom: 0.4 (subtle glow)
- Phosphor: 0.5 (medium warmth)
[Live preview updates as you adjust]
Screen 2: Color Palette
- Selected: "Amiga Workbench 3.1 MagicWB"
- 32-color palette previewed on UI elements
[Or: select anchor colors for custom OKLCH generation]
Screen 3: Theme & Accessibility
- Theme: Dark
- Reduced motion: No
- High contrast: No
# 4. Desktop appears with default icons:
[Terminal] [Dashboard] [Claude] [Disk]
Taskbar at bottom with clock and status indicators
# 5. Double-click Terminal icon
New terminal window opens with PTY session
Amiga-style titlebar: [Close] Terminal - bash [Zoom][Depth]
Multi-Window Workflow
# Typical GSD-OS session with multiple windows:
# Open dashboard (F3 or double-click icon)
Dashboard window shows: Phase 4 in progress, 3/8 complete
# Open terminal (F2 or double-click icon)
Terminal window opens alongside dashboard
# In terminal, check project status:
$ skill-creator status
Skills: 12 installed, 8 loaded (12,400/20,000 chars)
Pending suggestions: 2
# Depth-cycle windows (Ctrl+Shift+D or click depth gadget)
Dashboard moves to front, terminal behind it
# Open Claude session from system menu
Third window opens with Claude interaction
# Arrange windows:
Dashboard (left half) | Terminal (right half)
Claude minimized to icon area
# File watcher triggers:
[.planning/STATE.md changed]
Dashboard auto-refreshes to show updated session state
# Process monitor (System Menu > Process Monitor):
FPS: 58/60 | GPU: 42MB | PTY: 1 active | Claude: 1 active
Keyboard-Only Navigation
# Complete workflow using only keyboard:
# 1. Open system menu
F1
# Menu appears with options: Terminal, Dashboard, Claude, Settings...
# 2. Select "Terminal" with arrow keys and Enter
Arrow Down > Arrow Down > Enter
# New terminal window opens and receives focus
# 3. Run a GSD command
$ skill-creator status
# Output appears in terminal
# 4. Switch to Dashboard (open alongside terminal)
F3
# Dashboard window opens
# 5. Cycle between windows
Ctrl+Tab
# Focus moves from Dashboard to Terminal
# 6. Bring terminal to front (if behind dashboard)
Ctrl+Shift+D
# Terminal depth-cycles to front
# 7. Snap terminal to left half of screen
# (drag with Alt+arrow or use snap shortcut)
Alt+Left
# Terminal occupies left 50% of screen
# 8. Snap dashboard to right half
Ctrl+Tab # focus dashboard
Alt+Right # snap to right half
# 9. Split-screen workflow established:
# [Terminal | Dashboard] side by side
Custom Palette Generation
# In calibration wizard, Screen 2 (Palette):
# Select "Custom" instead of a preset
# Choose 2 anchor colors:
Anchor 1: #CC5500 (burnt orange - from fox watercolor)
Anchor 2: #1A3A5C (deep navy blue)
# OKLCH algorithm generates 32-color palette:
Step 1: Convert anchors to OKLCH color space
#CC5500 -> L:0.62 C:0.18 H:55
#1A3A5C -> L:0.30 C:0.08 H:250
Step 2: Generate hue distribution
30 additional colors distributed across hue wheel
Lightness controlled: 5 levels from 0.15 to 0.90
Chroma controlled: neutral grays + saturated accents
Step 3: Assign functional roles
Colors 0-3: Window chrome (titlebar, borders, background, text)
Colors 4-7: UI accents (selection, focus, hover, active)
Colors 8-15: Palette-indexed content colors
Colors 16-23: Extended content and status colors
Colors 24-31: Reserved for terminal and syntax highlighting
# Preview applies immediately to all UI elements
# Save stores palette in local config
WebGL Shader Pipeline Architecture
The CRT engine implements a multi-pass render-to-texture pipeline using WebGL2 framebuffers. On each frame, the entire UI is first rendered to an offscreen framebuffer (the "scene texture"). The CRT distortion pass reads this texture and writes to a second framebuffer, applying the barrel distortion transform per-fragment. The CRT post-processing pass reads the distorted texture and writes to the final screen framebuffer, applying scanlines, bloom, and color fringe as per-fragment operations.
The barrel distortion is implemented as a radial coordinate transform in the fragment shader: for each output pixel, the shader computes the corresponding input UV coordinate by applying a polynomial distortion function parameterized by the curvature value. The function maps normalized screen coordinates through uv = uv * (1.0 + curvature * dot(uv, uv)), which produces the characteristic CRT bulge. Edge pixels map to UV coordinates outside [0,1], which are clamped to black — creating the natural vignette at screen edges.
Scanlines are generated by modulating the fragment color based on vertical screen position: color *= 0.5 + 0.5 * sin(gl_FragCoord.y * PI * scanline_density). This produces alternating bright and dark horizontal bands. The density parameter controls how many scanlines appear per physical pixel row. At density 1.0, each physical row alternates; at 0.5, scanlines are spaced farther apart.
Bloom is implemented as a two-pass Gaussian blur on the bright regions of the scene. Fragments above a luminance threshold are extracted, blurred horizontally, then blurred vertically, and the result is composited back onto the scene with the bloom intensity as the blend factor. This is done in separate passes to keep the blur kernel separable (O(n) rather than O(n^2) per pixel).
Copper List System
The copper list (desktop/src/engine/copper-list.ts) is a direct software analog of the Amiga's Copper coprocessor. The Amiga Copper was a programmable display controller that could write to hardware registers on specific scanlines — enabling per-scanline palette changes, split screens, and gradient effects. In GSD-OS, the copper list is encoded as an Nx1 RGBA texture where N is the virtual scanline count (default 256). Each texel encodes two palette indices (R and G channels) and a blend factor (B channel). The palette background shader reads this texture and uses the blend factor to interpolate between the two referenced colors, producing smooth gradients.
Three built-in copper programs are provided: "gradient" (smooth blend across all 256 lines between two palette colors), "raster-bars" (colored horizontal bands reminiscent of classic Amiga demos), and "flat" (single solid color). Custom copper programs can be defined as arrays of { startLine, endLine, color1Index, color2Index, blend } entries, which are compiled into the texture at load time.
The copper list texture is uploaded to the GPU once at creation and only re-uploaded when the program changes, making the per-frame cost of the background rendering essentially free — a single texture lookup per fragment in the palette background shader.
IPC Architecture and Benchmarking
The frontend communicates with the Rust backend through Tauri's IPC system, which serializes function calls as JSON messages over a platform-specific transport (Unix domain sockets on Linux/macOS, named pipes on Windows). The IPC module (desktop/src/ipc/) provides several communication patterns: request/response (invoke a Rust command and await the result), event streaming (subscribe to a Tauri event channel for continuous data), and channel-based streaming (bidirectional data flow for PTY sessions).
IPC benchmarking (desktop/src/ipc/benchmark.ts) measures round-trip latency and throughput for each communication pattern. Typical measurements on commodity hardware: invoke round-trip is 0.5-2ms, event delivery is 0.1-0.5ms, and channel throughput is 50-100MB/s for PTY data streaming. These numbers ensure that the IPC layer is not a bottleneck for any user-visible operation — the most latency-sensitive operation (keyboard input to PTY output) completes well under the 16ms frame budget.
Palette Texture Pipeline
The 32-color palette is uploaded to the GPU as a 32x1 RGBA texture. Each texel stores one palette color. UI elements reference colors by palette index (0-31), which is converted to a texture coordinate (index/32.0) for lookup in the shader. This indirection is what enables instant re-theming: changing the palette only requires uploading a new 32x1 texture. Every element in the scene that references palette colors automatically displays the new colors on the next frame, with no per-element updates required.
The palette texture is stored in linear color space (not sRGB) to ensure correct blending in the shader. The OKLCH-to-linear-RGB conversion happens once during palette generation, and the final sRGB conversion happens in the shader's output stage. This pipeline ensures physically correct color mixing when the CRT post-processing shader blends adjacent scanline colors for the bloom effect.
Tauri Build and Deployment
GSD-OS is distributed as a native binary compiled by Tauri. The build process has two stages: the Vite frontend build produces a static bundle in desktop/dist/, and the Tauri/Rust build produces a platform-specific binary that embeds the frontend bundle. Build requirements are Node.js 18+, npm, Rust toolchain (stable), and platform-specific system libraries for Tauri (on Linux: libwebkit2gtk-4.1-dev, libappindicator3-dev, librsvg2-dev).
# Build dependencies (Ubuntu/Debian):
sudo apt install -y libwebkit2gtk-4.1-dev \
libappindicator3-dev librsvg2-dev \
build-essential libssl-dev
# Build dependencies (macOS):
xcode-select --install
# Build dependencies (Windows):
# Install Visual Studio Build Tools with C++ workload
# Development build:
cd desktop && npm install
npm run tauri dev
# Production build:
npm run tauri build
# Linux: src-tauri/target/release/bundle/appimage/gsd-os_*.AppImage
# macOS: src-tauri/target/release/bundle/dmg/GSD-OS_*.dmg
# Windows: src-tauri/target/release/bundle/msi/GSD-OS_*.msi
IPC Security Model
Tauri's IPC security model is allowlist-based. The tauri.conf.json configuration specifies which IPC commands are available to the frontend and which system capabilities they can access. GSD-OS restricts file system access to the project directory and .planning/ subdirectory — the frontend cannot read or write arbitrary files on the system. PTY sessions are scoped to the user's default shell and inherit the user's environment, but the frontend cannot spawn arbitrary processes outside the PTY interface.
All IPC commands validate their arguments on the Rust side before execution. File path arguments are canonicalized and checked against the allowed directory list. PTY session IDs are validated against the active session pool. Window management commands are restricted to the application's own window. This defense-in-depth approach means that even if the frontend's TypeScript code were compromised, the Rust backend would reject unauthorized operations.
# IPC security boundaries:
File System: Restricted to project root + .planning/
PTY: User's default shell only, no arbitrary process spawn
Window: Application window only, no access to other windows
Dialogs: Native file picker restricted to project directory
Network: No direct network access from IPC (use PTY for curl, etc.)
# Audit IPC commands:
grep -r "#[tauri::command]" src-tauri/src/
# Lists all registered IPC command handlers
Performance Tuning
The CRT shader pipeline is the primary GPU consumer. On integrated graphics (Intel UHD, AMD Vega), expect 45-60 FPS at 1280x800 with full shader effects. On discrete GPUs, the shader cost is negligible. If frame rates drop below 30 FPS, reduce CRT effects through the calibration wizard: set scanline density to 0.5, disable bloom (0.0), and reduce curvature to 0.1. These are the most expensive shader operations.
The process monitor (System Menu > Process Monitor) provides per-frame timing breakdown: render time, shader time, compositor time, and IPC overhead. If IPC overhead is high, check the file watcher debounce interval — rapid .planning/ file changes can flood the event bus. The default debounce is 500ms, which can be increased to 2000ms for slow systems:
# Adjust file watcher debounce (in Rust config):
// src-tauri/src/watcher.rs
const DEBOUNCE_MS: u64 = 2000; // Default: 500
# Monitor rendering performance:
# Open Process Monitor from System Menu
# Key metrics:
# Frame Time: should be < 16ms for 60fps
# Shader Time: CRT passes, should be < 8ms
# PTY Throughput: bytes/sec from terminal sessions
# Watcher Events: debounced event count per minute
For headless or CI environments where the desktop is not needed, GSD-OS's backend capabilities (file watching, dashboard generation) can be used independently through the CLI without launching the Tauri application. The serve-dashboard.mjs script provides dashboard access via HTTP without requiring the full desktop environment.
Log Files and Diagnostics
GSD-OS writes diagnostic logs to the application data directory under a logs/ subdirectory. Log files include:
gsd-os.log— General application log with startup events, IPC command invocations, and error reports.pty.log— PTY session lifecycle events: open, close, resize, and any errors during data streaming.watcher.log— File watcher events including debounce statistics and regeneration triggers.render.log— WebGL rendering statistics: frame times, shader compilation results, GPU memory allocation.
Logs rotate daily with a 7-day retention policy. For verbose debugging, set RUST_LOG=debug before launching GSD-OS to enable detailed Rust backend logging. For frontend debugging, open the Tauri development tools with Ctrl+Shift+I (only available in development builds) to access the browser console and network inspector.
Updating and Versioning
GSD-OS follows semantic versioning aligned with the skill-creator core. The desktop application version is tracked separately from the frontend module versions (engine, wm, shell, calibration). When updating GSD-OS, both the Rust backend and TypeScript frontend must be rebuilt. The update process is:
# Pull latest source
git pull origin main
# Rebuild frontend
cd desktop && npm install && npm run build
# Rebuild backend (includes bundling new frontend)
cd src-tauri && cargo build --release
# Verify version
./target/release/gsd-os --version
Configuration files (calibration settings, window state, palette selections) are preserved across updates because they are stored in the user's application data directory, not in the application bundle.
Resource Requirements
GSD-OS has modest resource requirements for a native desktop application:
| Resource | Minimum | Recommended | Notes |
|---|---|---|---|
| RAM | 256MB | 512MB | Mostly WebGL buffers and PTY sessions |
| GPU | WebGL2 support | Any discrete GPU | Integrated graphics work with reduced CRT effects |
| Disk | 100MB | 200MB | Application binary + dependencies |
| CPU | Dual-core | Quad-core | Shader work is GPU-bound; CPU handles PTY and IPC |
| Display | 1280x800 | 1920x1080 | Higher resolutions increase shader workload |
At higher display resolutions (4K), the CRT shader processes more fragments per frame. This is typically handled by the GPU without issues on discrete graphics, but integrated graphics at 4K may drop below 30 FPS with full CRT effects enabled. The calibration wizard's "Recommended" preset automatically adjusts effect intensity based on detected GPU capabilities.
Getting Started with GSD-OS
To start using GSD-OS, you need three things: a built application binary, a project with GSD initialized (a .planning/ directory), and a WebGL2-capable display. The simplest path is the development build:
# Prerequisites:
# - Node.js 18+ and npm
# - Rust stable toolchain (rustup.rs)
# - Platform-specific Tauri dependencies (see SysAdmin section)
# Clone and build:
git clone https://github.com/Tibsfox/gsd-skill-creator.git
cd gsd-skill-creator/desktop
npm install
# Launch in development mode (with hot reload):
npm run tauri dev
# First launch: calibration wizard appears
# Subsequent launches: desktop appears directly
# To use with an existing project:
# Navigate to the project directory before launching, or
# use the File menu to open a project directory
On first launch, the calibration wizard guides you through CRT settings, palette selection, and theme mode. The "Recommended" CRT preset and "Amiga Workbench 3.1" palette provide the most authentic experience. If you prefer a clean, modern look, select the "Fox Default" palette and set all CRT parameters to their minimum values. You can re-calibrate at any time from the system menu.
Once on the desktop, start by opening a Terminal window (F2 or double-click the Terminal icon) and a Dashboard window (F3 or double-click the Dashboard icon). The terminal provides full shell access for running GSD commands and skill-creator operations. The dashboard shows your project state. These two windows, side by side, form the core GSD-OS workflow.
Desktop vs CLI: When to Use Which
| Scenario | Recommended | Reason |
|---|---|---|
| Quick command execution | CLI | Faster to type than navigate windows |
| Multi-phase project session | GSD-OS | Dashboard + terminal side-by-side, auto-refresh |
| Teaching or demos | GSD-OS | Visual impact, self-contained environment |
| CI/CD pipeline | CLI | No display needed, JSON output for scripts |
| Remote SSH session | CLI | No GUI available |
| Long-running phase execution | GSD-OS + tmux | tmux persistence + visual dashboard monitoring |
| Reviewing project status | GSD-OS | Dashboard is richer than CLI status output |
| Headless server | CLI + serve-dashboard.mjs | Dashboard via browser, CLI for commands |
Troubleshooting
Black screen on launch
This typically indicates a WebGL2 initialization failure. Verify that your GPU supports WebGL2 by opening chrome://gpu in Chromium or checking about:support in Firefox. On Linux, ensure the correct GPU driver is installed (Mesa for Intel/AMD, proprietary for NVIDIA). If WebGL2 is unavailable, GSD-OS falls back to a software renderer with CRT effects disabled — but this fallback may not activate if the WebGL context creation itself fails. Try running with the environment variable WEBKIT_DISABLE_DMABUF_RENDERER=1 on Linux to work around certain driver issues.
Terminal input not working
If the terminal window opens but does not accept keyboard input, the PTY session may have failed to open. Check the process monitor or the Tauri dev tools console (Ctrl+Shift+I in development mode) for error messages. Common causes: the default shell is not found (set SHELL environment variable), the portable-pty crate cannot allocate a PTY (check /dev/pts permissions on Linux), or the PTY session was opened but immediately closed due to a shell configuration error in .bashrc or .zshrc.
Dashboard not auto-refreshing
Verify that the file watcher is running by checking the status indicator in the taskbar (a small icon that blinks when events are received). If the indicator is static, the watcher may have crashed. Restart GSD-OS to reinitialize the watcher. If the watcher is running but dashboards are not updating, check that dashboard_generation is enabled in .planning/skill-creator.json. Also verify that the .planning/ directory is within the file watcher's monitored scope — if the project directory was moved after GSD-OS was started, the watcher may be monitoring the old path.
High GPU usage or low frame rate
Open the process monitor and check the shader time metric. If it exceeds 12ms per frame, reduce CRT effects through Settings > Recalibrate Display. The most expensive effects in order are: bloom (requires multi-pass Gaussian blur), scanlines at density > 1.5 (high-frequency sin() computation per pixel), and curvature > 0.7 (complex UV remapping). Setting all CRT parameters to 0.0 eliminates the shader cost entirely while retaining the Amiga-style UI chrome.
Calibration settings not persisting
Calibration settings are stored in the application's local data directory. On Linux, this is typically ~/.local/share/gsd-os/. On macOS, ~/Library/Application Support/gsd-os/. On Windows, %APPDATA%/gsd-os/. If settings reset on every launch, verify that the application has write permissions to this directory. If running GSD-OS from a read-only filesystem or sandboxed environment, the config directory may need to be explicitly configured via the TAURI_CONFIG_DIR environment variable.
Window positions reset on restart
Window state is saved to the same local data directory as calibration settings. If window positions are not persisting, the issue is the same as calibration persistence — check write permissions to the application data directory. If the window state file becomes corrupted (causing windows to appear offscreen or at zero size), delete the window-state.json file from the data directory. GSD-OS will recreate it with default positions on the next launch.
tmux sessions not detected
GSD-OS detects tmux by checking for the tmux binary in the system PATH. If tmux is installed but not detected, ensure that the PATH environment variable includes the directory containing the tmux binary. On macOS with Homebrew, this is typically /opt/homebrew/bin. If tmux is detected but sessions cannot be listed, check that the tmux server is running (tmux ls from a terminal). GSD-OS cannot start the tmux server itself — at least one tmux session must already exist for the attach feature to work.
Fonts appear blurry or incorrectly sized
Font rendering in the terminal window uses xterm.js with the WebGL addon. If fonts appear blurry, check the display scaling settings in your operating system. High-DPI displays (Retina, 4K) require that GSD-OS correctly detects the device pixel ratio. Tauri handles this automatically on most systems, but some Linux window managers report incorrect DPI values. Set GDK_SCALE=2 and GDK_DPI_SCALE=0.5 environment variables before launching GSD-OS to force correct scaling on problematic Linux setups.
Copper list background not rendering
The copper list background requires the palette background shader to compile successfully. If the background is solid black instead of showing gradient or raster bar effects, check the render log for shader compilation errors. The most common cause is a WebGL2 feature that the GPU driver does not support. Try setting the copper program to "flat" (single solid color) to verify the shader pipeline works at all, then switch to "gradient" or "raster-bars" to isolate the issue. On older Intel integrated graphics, the copper list may need to use a reduced scanline count (128 instead of 256) to stay within texture size limits.
Claude session window shows "disconnected"
The Claude session monitor checks session health periodically. If the monitor shows "disconnected," verify that Claude Code is installed and accessible in the system PATH. The Rust backend starts Claude sessions via the CLI, so the claude binary must be available. Also check that the ANTHROPIC_API_KEY environment variable is set. If the key is set but sessions still fail, check the application log (gsd-os.log) for the specific error message from the Claude session manager.

