π Runner Service β REPL Runtime Engine
The runner/
service is the runtime component of the Devex platform.
It is a lightweight WebSocket server embedded inside the userβs REPL pod. The runner connects directly to the frontend, allowing real-time:
- β’File browsing and editing
- β’Terminal interaction via PTY
- β’Bi-directional event-driven communication
π Directory Structure
Path | Description |
---|
cmd/ | Entrypoint and route setup |
services/repl/route.go | WebSocket endpoint handler |
pkg/ws | WebSocket abstraction and event routing layer |
pkg/fs | Filesystem utils: read directory, patch files |
pkg/pty | Terminal session manager using PTY |
π API Endpoint
GET /api/v1/repl/ws
Defined in
route.go
, this WebSocket endpoint serves as the
main connection point between the frontend and the REPL container.
π WebSocket Event Flow
The WebSocket connection is
event-based, using custom handlers via the
pkg/ws
system.
Hereβs how each event is handled inside the runner:
π‘ Connection
- β’Triggered: When the frontend successfully connects
- β’Action: Emits the
Loaded
event with the directory tree at /workspaces
ws.On("Connection", func(data any) {
rootContents, _ := fs.FetchDir("/workspaces", "")
ws.Emit("Loaded", map[string]any{
"rootContents": rootContents,
})
})
π fetchDir
- β’
Purpose: Fetches the contents of a directory (files & subfolders)
- β’
Payload:
- β’
Emits: fetchDirResponse
with folder contents
ws.Emit("fetchDirResponse", {
"contents": [...],
"path": "subdir/path"
})
π fetchContent
- β’
Purpose: Fetches the content of a single file
- β’
Payload:
- β’
Emits: fetchContentResponse
with file content or error
πΎ updateContent
- β’
Purpose: Applies a patch to a file (diff-based updates)
- β’
Payload:
{
"path": "index.js",
"patch": [...]
}
- β’
Emits: updateContentResponse
with success or error
π₯οΈ requestTerminal
- β’
Purpose: Starts a new PTY terminal session for the user
- β’
Flow:
- β’A session is created using
pty.CreateSession
- β’On receiving terminal data, it emits
terminalResponse
- β’On close, emits
terminalClosed
session.SetOnDataCallback(func(data []byte) {
ws.Emit("terminalResponse", string(data))
})
β¨οΈ terminalInput
- β’
Purpose: Sends user input to the terminal session
- β’
Payload:
π§± Internal Packages
Each major functionality is implemented in modular packages. See individual documentation for detailed internals:
WebSocket handler with event routing system
Handles On
, Emit
, custom event types, and JSON marshalling.
Filesystem abstraction layer
Supports reading directories, fetching files, and applying patches.
Terminal session manager using PTY
Manages session creation, input, data output, and session lifecycle.
π§ͺ Runtime Environment
The runner is deployed inside each userβs REPL pod via Kubernetes, and interacts with the user-specific volume mounted at /workspaces
.
- β’Runner container is built from the main Dockerfile
- β’Connects automatically with the frontend once the pod is ready
- β’Exposes internal REST/WebSocket interface at
/api/v1/repl/ws
π§© Responsibilities
Task | Handled by |
---|
Serve WebSocket Endpoint | services/repl/route.go |
Emit & Handle Events | pkg/ws |
File operations | pkg/fs |
Terminal session | pkg/pty |
π§ Future Improvements
- β’Add support for file uploads and deletions
- β’Terminal resize support
- β’Rate limiting or sandbox enforcement per session
π Related
- β’Main backend API:
/core
- β’Kubernetes setup:
/k8s
- β’Templates used at REPL creation:
/templates