Skip to content

Architecture

Keys edited this page Jul 31, 2026 · 1 revision

Architecture

The core is deliberately headless. UI, manuals, and WebAssembly depend on the shell; the shell does not depend on a terminal framework.

custom UI ── mountShell() ── createShell()
                               ├─ parser and expansion
                               ├─ bounded MemoryFS
                               ├─ built-ins and OS profile
                               ├─ lazy manual resolver
                               └─ lazy Wasm line filter

Command flow

  1. The parser turns shell text into linked jobs and pipelines.
  2. Variables, assignments, and redirect paths are expanded.
  3. Redirects read or write only the virtual filesystem.
  4. Built-in or application-registered handlers receive arguments and a limited context containing virtual state, input, cancellation, and command dispatch.
  5. Results are normalized to { code, stdout, stderr } and checked against the configured limits.

Custom handlers are registered after built-ins, so an application can replace a built-in intentionally. Pipelines are sequential and pass text output to the next command; there are no host processes, job control, devices, or sockets.

Source map

Area Source
Shell state and dispatch javascripts/shell.js
Grammar and expansion javascripts/parser.js
Virtual filesystem javascripts/fs.js
Built-ins and profiles javascripts/commands.js, javascripts/profiles.js
Optional browser UI javascripts/ui.js
Manual resolver javascripts/man.js

WebAssembly

The Rust module accelerates only large literal line filtering. JavaScript remains the normal path for short input.

  • Wasm is off unless the caller configures it, for example with wasm: "auto".
  • Loading is lazy; await shell.prepare("wasm") is an optional warm-up.
  • Inputs below 256 KiB stay in JavaScript.
  • The module has no imports, WASI, allocator, or bindings framework. Its raw ABI is versioned and validated before use.
  • Fetch, validation, or execution failure falls back to JavaScript.

Run npm run build && npm run benchmark before changing the threshold or ABI. Artifact budgets and parity checks live in javascripts/benchmark.js, which is the source of truth for current limits and measurements.

Clone this wiki locally