// ARB — A TUI FOR EVERY PIPELINE

arb v0.1.1 · pipe → dynamic TUI/web · original language on fusevm + Cranelift JIT · jq/xpath/css/yq superset · Tcl/Tk-flavored DSL · MIT · M0–M8 shipped: query engine, controls, web target, actors, package manager, LSP/DAP

Reference Report GitHub Issues
// Color scheme

>_ARB REFERENCE

Pipe a Unix stream into arb and it spawns a dynamic TUI (ratatui) or a served zgui web dashboard, built from a declarative, Tcl/Tk-flavored spec. arb is a jq/xpath/css/yq superset, an interactive megafilter/map over the live passthrough, and an original language that runs on the fusevm bytecode VM + three-tier Cranelift JIT — the same engine behind zshrs, stryke, rubyrs, and elisp. Milestones 0–8 ship: the zero-config live-tail, the spec interpreter with multi-widget render, the jq/xpath/css/yq query pipeline, interactive controls, Expect reactions, the served web target, Akka-style actors, the package manager, and LSP/DAP editor tooling.

What it is

arb turns a pipe into an interface. Drop it into a pipeline — find / | arb — and instead of scrolling past text you get a live view of the stream. The full language lets a small declarative spec describe widgets, layout, a uniform query over any format, and interactive controls that feed back into the passthrough, so arb can shape the downstream output mid-pipe, not just display it.

It is an original language in stryke's class — not a port. It reuses mechanics from its siblings (fusevm embedding, the rkyv bytecode cache, the LSP/DAP stdio shape, the package-manager ABI) but the lexer, parser, AST, lowering, and semantics are arb's own. Standalone crate, MIT, deliberately lean — rubyrs-scale, not stryke-scale.

The world-first: synthesis + ecosystem

No single leg is new — Tcl/Tk (1988), Expect (1990), dasel (unified query), ratatui (TUI), Streamlit / textual serve (served web UI) are all prior art. arb's novelty is the combination: a pipe-native, dual-target (terminal + web), component-generating UI language with a shareable dashboard registry. There is no registry of installable pipeline TUIs today — cmd | arb sniffs the upstream command or data shape, resolves the matching arb-<tool> package, and renders. Every common pipeline (docker / kubectl / psql / nginx / git / systemctl) gets a shared, installable dashboard.

Try it

With no spec, arb synthesizes a full-screen tail of stdin — the zero-config path. With a spec (a .arb file or an -e one-liner) the interpreter reads the declarative language — widgets, source/out query pipelines, controls, reactions, and .x <- in binds — and renders it. With no controlling terminal on stdout (piped onward / redirected / CI) arb prints the parsed spec and each source's evaluated result instead of a TUI.

cargo install --path .

# zero-config: a live tail with count + rate; q / Esc / Ctrl-C quits
find / | arb

# a spec: a gauge fed by the live line count of the stream
seq 1 100000 | arb -e 'gauge .g -max 100000; source .g { in; count }'

# a filtered list: keep 5xx lines, drop health checks
tail -f access.log | arb -e 'list .l; source .l { in; match /5\d\d/; reject /health/ }'

arb today is a full query engine — a jq/xpath/css/yq superset, ~90 verbs over line, JSON, CSV/TSV, YAML, TOML, and HTML — with an expression layer (where/map/ternary) whose arithmetic lowers to fusevm bytecode, rendering into the full ratatui data-widget set — text/tail/list/gauge/linegauge/bars/histo/spark/sparkline/scatter/chart/map/calendar/table widgets, plus a scrollbar on overflowing lists (each -color themeable). It is interactive: the megafilter/map (type or bind a transform and the piped output reshapes live via input/apply/out), a fuzzy select mode (fzf as a one-widget spec), a sel selection list whose highlighted row is published as .<path>.sel, and stream reactions (expect /re/ → action). It also serves the same spec as a live browser dashboard (arb --serve, WebSocket push with a polling fallback) and ships a package manager (--install/--uninstall/--installed) to share dashboard specs. Akka-style actors ship (SPEC §15): actor NAME(state) { on MSG { … reply EXPR } } declarations backed by a real mpsc-mailbox thread-per-actor runtime (tell/ask/supervised pool), with two surfaces: a via NAME * N pipeline op that fans the stream across a worker pool in parallel, and session refs (spawn/pool + supervise) driven by tell/ask bind/expect actions in the TUI. Dashboards lay out on a proportional grid (rows "1 2 1"/cols "20c * 2*" fixed/percentage/weighted tracks, gap, layout horizontal), and a color-theme system of 31 palettes ported from the sibling iftoprs/htoprs apps (plus theme custom c1..c6) is always on — default neon-sprawl, set globally with arb --set-theme (~/.arb/config.toml) or per-run --theme, recoloring the whole TUI and the fzf picker from the palette. Inline rust { … } FFI blocks compile to a cached cdylib callable from expressions. Nothing is faked — unrecognized widget verbs are ignored so specs stay forward-compatible, and unbuilt features are absent, not stubbed.

The language (specified)

arb's syntax is Tcl/Tk-flavored but is not Tcl — no $ substitution, no [cmd] substitution, no expr{}. Commands take args and verbatim { } blocks; widget paths are dot-hierarchical (.a.b.c), Tk-style. Variables are Python/Swift-lite (max = 100 immutable, var n = 0 mutable). The full grammar is in SPEC.md.

tail  .log  -label "requests"
table .t    -cols {ts level msg}
gauge .cpu  -label "cpu %" -max 100

source .t { in.json; each; where(is5xx); count; every 1s }
.cpu <- cpu_pct

filter .q                        # text box  -> .q
facet  .lv -field level          # facets    -> .lv selected set

out {
    where(match(.q))             # filter by the text box
    where(level in .lv)          # filter by facet selection
    map(x => pick(x, {ts msg}))  # MAP the passthrough, not just filter
}

Query — one engine over every format

A single query vocabulary works uniformly over JSON, XML, HTML, YAML, TOML, and CSV — a jq/xpath/css/yq superset.

jq / xpath / cssarb
.users[].namefield users; each; field name
.items[] | select(.price>10)field items; each; where(price>10)
//a/@hreffind a; attr href
div.card h2sel {div.card h2}

Milestones

arb landed in stages; the table reflects the current tree. The query engine, expression layer, interactive controls, reactions, web target, actor system, package manager, and LSP/DAP editor tooling are all built; native/cdylib packages and multi-version registry resolution remain planned. The full grammar is in SPEC.md.

MilestoneStateScope
M0 — Walking skeletonImplementedZero-config live-tail TUI (ratatui) + headless summary; count/rate header; ring buffer; q/Esc/Ctrl-C quit (src/main.rs).
M1 — Spec interpreter + widgetsImplementedTcl-flavored reader (src/lexer.rs, src/parser.rs, src/ast.rs); declarative widget/source interp + .x <- in binds; multi-widget render of text/tail/list (src/spec.rs, src/tui.rs).
M2 — Query pipeline + widgetsImplemented~90 source query verbs (a jq/xpath/css/yq superset) over line, JSON, CSV/TSV, YAML, TOML, HTML; numeric / stats / time-series (percentile, delta/cumsum, sma/ewma, median/stddev/bins); rendering into 25 -color-themeable widgets — text/tail/list/gauge/linegauge/bars/histo/spark/sparkline/scatter/chart/map/calendar/table/tabs/block/frame (the full ratatui set) plus composites logview/heatmap/treemap/gantt/diff/logo/rule and a scrollbar on overflow (src/query.rs, src/tui.rs).
M2+ — Presets / imports / expression layerImplementedStdlib + user preset dashboards; where(pred), sort / group / uniq; the expression layer (where/map/ternary) whose arithmetic lowers to fusevm bytecode (src/expr.rs).
M3 — Interactive controls + outImplementedThe megafilter/map — input fields + apply splice a live transform into source/out, reshaping the piped output as you type; plus the fuzzy select mode (fzf as a spec).
M4 — Expect + eventsImplementedStream reactions (expect /re/ → action) and Tk-style key binds (bind C-<key> set/quit), sharing one action vocabulary.
M5 — Web targetImplementedarb --serve: a std-only HTTP server renders the same spec as a live browser dashboard, pushing widget data over a hand-rolled WebSocket (no dependency) with a polling fallback (src/serve.rs).
M6 — ActorsImplementedAkka-style message-passing: actor NAME(state) { on MSG(p) { … reply EXPR } } declarations; one mpsc-mailbox OS thread per actor with tell/ask/supervised-pool semantics; handler bodies run arb expressions (fusevm) over state + params + locals; a via NAME * N pipeline op fans the stream across a pool in parallel; and session refs (spawn NAME = ACTOR(init) / pool NAME = ACTOR * N + supervise crash policy) are driven by tell/ask bind/expect actions in the TUI (src/actor.rs).
M7 — Package managerImplementedInstall / uninstall / list shareable dashboard specs (arb --install/--uninstall/--installed); install validates before adding. A remote registry plugs into the same resolver next.
M8 — LSP / DAPImplementedarb --lsp is a full stdio server: diagnostics (real source ranges, UTF-16 columns), documentSymbol/hover/completion/signatureHelp, definition/references/rename over widget paths, foldingRange, formatting, semanticTokens. arb --dap is a steppable debugger over the stream model — each line is a step, breakpoints are regex predicates, the stack is the query stages, evaluate runs the real expression evaluator (src/lsp.rs, src/dap.rs).
M9 — Layout & themesImplementedProportional grid layout — rows "1 2 1"/cols "20c * 2*" (fixed/percentage/weighted tracks), gap N, layout horizontal. A theme system of 31 palettes ported from the sibling iftoprs/htoprs apps + theme custom c1..c6; a theme is always on (default neon-sprawl), set globally via arb --set-theme (~/.arb/config.toml) or per-run --theme, recoloring the whole TUI + fzf picker from the palette (src/theme.rs).
M10 — Inline Rust FFIImplementedrust { pub extern "C" fn … } blocks compile to a cached cdylib (via fusevm) and are callable by name from the expression layer (src/rust_ffi.rs).

Architecture

arb's computational core runs on fusevm: the expression layer (src/expr.rs) lowers arithmetic to a fusevm::Chunk and executes on the shared VM (three-tier Cranelift JIT). Declarative widget/layout construction needs no VM and stays plain Rust — correct by design. The Tcl-flavored reader (src/lexer.rs, src/parser.rs, src/ast.rs) builds a Spec (src/spec.rs) that src/tui.rs renders and src/serve.rs serves over HTTP/WebSocket, with source bodies evaluated by the query pipeline (src/query.rs) over the live stream (src/stream.rs). Deps: fusevm, ratatui, clap, regex, serde_json/serde_yaml/scraper (formats), base64/percent-encoding (encode verbs), rayon (parallel fuzzy match), reedline (REPL).

src/lexer.rs     Tcl-flavored reader            (present)
src/parser.rs    widget cmds + expr grammar     (present)
src/ast.rs       syntax tree                    (present)
src/spec.rs      command tree -> Spec interp    (present)
src/expr.rs      expression -> fusevm::Chunk     (present)
src/query.rs     source query pipeline          (present)
src/actor.rs     actor system + via fan-out     (present)
src/theme.rs     31 color palettes + custom     (present)
src/rust_ffi.rs  inline rust { } FFI blocks     (present)
src/stream.rs    live stream state              (present)
src/tui.rs       ratatui backend + themes       (present)
src/serve.rs     HTTP + WebSocket web target    (present)
src/repl.rs      reedline REPL                  (present)
src/web.rs       static HTML export             (present)
src/lsp.rs src/dap.rs   stdio JSON-RPC          (present)

Transfers from siblings are mechanics only — fusevm embedding, the rkyv cache, the LSP/DAP stdio shape, the package-manager ABI. The language design (lexer / parser / AST / compiler / semantics) is arb-original.

Why arb

Pipe-native

Terminal-invoked, pipe-driven. No daemon. The web target spawns a local UI host on demand, like textual serve — not a server you run.

Dual target

The same spec renders to a ratatui TUI or a served zgui web page + WebSocket, sharing the cyberpunk HUD scheme with its sibling apps.

Megafilter/map, not just view

Interactive controls feed out, so arb sits mid-pipe and shapes what the downstream consumer receives — filter and map the passthrough live.

Shareable dashboards

A package manager (script + native packages) and a registry so the community publishes arb-<tool> dashboards — a TUI for every pipeline.

Building from source

arb builds as a standalone Rust crate:

# clone
git clone https://github.com/MenkeTechnologies/arb
cd arb

# build (debug)
cargo build

# run the M0 tail
find / | ./target/debug/arb

# install
cargo install --path .

License

arb is MIT licensed — free and open source. See LICENSE.

Repository & links