Skip to main content

Crate bastion

Crate bastion 

Source
Expand description

§bastion — block-aware web terminal

Serves a persistent, OSC 133–segmented shell to the browser over a WebSocket. Each session owns a PTY spawned with WezTerm’s shell integration injected, so the byte stream is cut into {command, output, exit} blocks and kept alongside a small raw-byte ring for reconnect replay.

§Quick start

use axum::Router;

let mgr = bastion::Manager::new();
let app: Router = Router::new().nest("/term", bastion::router(mgr));
let listener = tokio::net::TcpListener::bind("127.0.0.1:7681").await?;
axum::serve(listener, app).await.unwrap();

Routes (relative to wherever you mount the router):

  • GET / — SPA HTML
  • GET /api/sessions — list sessions
  • POST /api/sessions — create a session
  • DEL /api/sessions/:id — kill a session
  • GET /ws/:id — WebSocket

§WebSocket protocol

Client → server:

  • binary frames = stdin bytes (forwarded to PTY)
  • text JSON {type:"resize",cols,rows} | {type:"hello",have_up_to:N}

Server → client:

  • binary frames = raw PTY bytes (feed to xterm.js)
  • text JSON {type:"block",...record} | {type:"exit",code} | {type:"gap",from,to} | {type:"ready",seq}

Structs§

BlockRecord
Manager
SessionInfo

Functions§

router
Mount point-agnostic. Nest this wherever you want:

Type Aliases§

ShellFn
A function that wraps the SPA body in HTML chrome (title + whatever nav/branding the host app wants). Called with (title, body_html), must return the complete HTML document string.