Skip to content
Peter Pak edited this page Apr 15, 2026 · 5 revisions

GUI

The RocketSmith GUI is an offline-first web dashboard that displays project data in real time as the agent works. It runs as a single index.html file that can be opened via file:// (no server needed) or served by the built-in GUI server for live updates.

The gui subagent (agents/gui.md) manages the GUI lifecycle — starting/stopping the server and navigating to pages. Domain agents (openrocket, cadsmith, etc.) generate the data; the gui agent ensures it's visible.

Architecture

index.html (project root)
    ↓ loads
gui/main.js (React bundle)
gui/data.js (offline data snapshot)
    ↓ connects to
WebSocket server (live file-change events)
  • Offline mode: data.js contains a snapshot of all project files. The page works without a server.
  • Live mode: The WebSocket server watches the project directory and pushes file-change events. The frontend patches window.__OFFLINE_DATA__ in memory so all reads stay current.
  • Dev mode: Vite HMR for frontend development. Proxies /ws and /api to the Python backend.

The frontend never fetches files directly. All data reads go through window.__OFFLINE_DATA__ — a JavaScript object containing the full project state. Text files are stored as strings (JSON parsed inline), binary files (STL) as {"__b64__": "<base64>"} objects converted to blob URLs on demand. Routes like /parts/nose_cone are just React Router keys — the component looks up gui/parts/nose_cone.json in the in-memory bundle.

MCP Tools

Tool Description
gui_server Start, stop, or dev-launch the GUI server.
gui_navigate Navigate the GUI to a specific route path via WebSocket command.

gui_server

Actions:

Action What it does
start Copies built GUI files to the project, writes data.js snapshot, starts the Python backend, opens index.html in the browser. Called automatically by rocketsmith_setup — use directly to recover if the GUI didn't open.
dev Starts Vite HMR + Python WebSocket server. If a production server is already running, piggybacks on it (no duplicate WS server).
stop Kills all GUI server processes for the project (reads PID files).

Parameters:

  • action (required): "start", "dev", or "stop"
  • project_dir: Path to the project directory
  • pid: (stop only) Kill a specific PID instead of reading the PID file
  • host: Bind address (default 127.0.0.1)
  • port: (start only) Backend port (default 24880)

Dev mode ports:

  • Vite: 5173
  • WebSocket (standalone): 24881
  • Production backend: 24880

Dev mode detects a running production server on 24880 and proxies to it instead of starting a second WebSocket server.

gui_navigate

Sends a navigation command over WebSocket to all connected GUI clients.

Parameters:

  • path (required): Route path to navigate to

Pages & Routes

The GUI uses a HashRouter. URLs look like http://127.0.0.1:5173/#/parts/nose_cone.

Route Page Description
#/ Agent Feed Live dashboard with draggable cards. Shows part cards, component tree, flight simulation, build progress, and session log. Navigate here when switching to a new task.
#/flights Flight Viewer Flight simulation charts rendered from openrocket/flights/*.json timeseries data.
#/component-tree Component Tree Rocket profile visualization, CG/CP/stability badges, and hierarchical component list with DFAM fate annotations.
#/assembly Assembly Viewer 3D spatial layout of assembled parts from gui/assembly.json.
#/parts/<name> Part Detail Tabbed view with 3D model viewer and build123d source code for a specific part.

Part routes use #/parts/<name> — no .json extension, no gui/ prefix. Routes are just keys for React Router — the frontend never fetches files directly. All data is read from the in-memory window.__OFFLINE_DATA__ bundle, where the part is stored under the key gui/parts/<name>.json.

Navigation Pattern

Navigate to a detail page (e.g. #/flights) to present finished results. When the pipeline moves on to the next piece of work, navigate back to #/ so the user sees new cards appear in the Agent Feed. The feed auto-focuses on the most recently updated card.

gui_navigate(path="#/flights")   # present flight results
# ... cadsmith starts generating parts ...
gui_navigate(path="#/")          # return to feed for new activity

Agent Feed

The default page (/) is the Agent Feed — a grid-based dashboard where cards appear as the agent works.

Cards

Card Content Default Size
Part Card (one per part) Tabbed: 3D model viewer + source code 3 cols × 4 rows
Component Tree Rocket profile SVG (with hover highlighting), CG/CP/stability, component list 3 cols × 3 rows
Flight Simulation Summary badges (apogee, Vmax, stability), tabbed charts (altitude, velocity, stability, thrust) with burnout/apogee markers 3 cols × 3 rows
Build Progress Per-part preview generation status with progress bars 2 cols × 1 row
Session Log Timestamped log of agent actions 2 cols × 1 row

Grid System

  • Fixed cell size: 280px wide × 180px tall, 16px gap
  • Grid expands to fill the viewport; scrolls if cards extend beyond
  • Cards are placed at explicit grid positions (col, row) with explicit spans
  • Drag-and-drop to reposition cards
  • Resize handles on right and bottom edges
  • Layout persisted to localStorage under rocketsmith:preferences
  • "Reset Layout" button clears stored positions and auto-places cards
  • "Auto-focus" toggle scrolls to the active (most recently updated) card
  • Active card highlighted with orange border

Data Flow

  1. WebSocket server sends snapshot events on connect (replays current project state)
  2. Live file-change events update the in-memory data bundle
  3. Cards read from window.__OFFLINE_DATA__ via fetchJson()/fetchText()/fileUrl()
  4. Binary files (STL) are base64-encoded and converted to blob URLs for Three.js

File Layout

All GUI-related files live under gui/ in the project directory:

gui/
├── main.js              ← React bundle (from Vite build)
├── data.js              ← Offline data snapshot (generated by server)
├── .gui.pid             ← Production server PID
├── .gui-dev.pid         ← Dev server PIDs
├── files-tree.json      ← Directory tree snapshot
├── component_tree.json  ← Component hierarchy with DFAM annotations
├── assembly.json        ← Spatial layout for 3D viewer
├── parts/               ← Per-part JSON metadata
├── logs/session.jsonl   ← Agentic session log
├── progress/            ← Per-part preview generation progress
└── assets/
    ├── stl/             ← STL meshes (generated by preview tool)
    ├── png/             ← PNG thumbnails
    ├── gif/             ← Rotating GIF animations
    └── txt/             ← ASCII animation frames

Offline Data Bundle

data.js sets window.__OFFLINE_DATA__ with:

window.__OFFLINE_DATA__ = {
  filesTree: [...],           // Recursive directory tree
  projectInfo: { name, path },
  files: {
    "gui/component_tree.json": { ... },  // Parsed JSON
    "gui/logs/session.jsonl": "...",     // Raw text
    "gui/assets/stl/nose_cone.stl": { "__b64__": "..." },  // Base64 binary
  }
};
  • Text files stored as strings (JSON parsed inline)
  • Binary files (STL) stored as {"__b64__": "<base64>"} → converted to blob URLs by fileUrl()
  • Generated on server start and shutdown; live events keep the in-memory copy current

Clone this wiki locally