-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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.jscontains 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
/wsand/apito 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.
| 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. |
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 (default127.0.0.1) -
port: (start only) Backend port (default24880)
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.
Sends a navigation command over WebSocket to all connected GUI clients.
Parameters:
-
path(required): Route path to navigate to
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.
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
The default page (/) is the Agent Feed — a grid-based dashboard where cards appear as the agent works.
| 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 |
- Fixed cell size:
280pxwide ×180pxtall,16pxgap - 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
localStorageunderrocketsmith: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
- WebSocket server sends snapshot events on connect (replays current project state)
- Live file-change events update the in-memory data bundle
- Cards read from
window.__OFFLINE_DATA__viafetchJson()/fetchText()/fileUrl() - Binary files (STL) are base64-encoded and converted to blob URLs for Three.js
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
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 byfileUrl() - Generated on server start and shutdown; live events keep the in-memory copy current