// ARB — A TUI FOR EVERY PIPELINE

arb v0.0.1 · pipe → dynamic TUI/web · original language targeting fusevm + Cranelift JIT · jq/xpath/css/yq superset · Tcl/Tk-flavored DSL · MIT · M0–M2: live-tail + spec interpreter + query pipeline (expanding)

Report GitHub Issues
// Color scheme

>_ARB REFERENCE

Pipe a Unix stream into arb and it spawns a dynamic TUI (ratatui today, a served zgui web page later) 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 targets the fusevm bytecode VM + three-tier Cranelift JIT — the same engine behind zshrs, stryke, rubyrs, and elisp. Early — Milestones 0–2 ship the zero-config live-tail, the Tcl-flavored spec interpreter with multi-widget render, and the JSON-aware source query pipeline (still expanding).

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 from M0. With a spec (a .arb file or an -e one-liner) the M1/M2 interpreter reads the declarative subset — widgets, source query pipelines, 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/ }'

The verbs live today are in, match/grep, reject/grepv, field N/field NAME, count, rate, and tally — over line and JSON streams (in.json, nested key paths) — rendering into text/tail/list/gauge/bars/histo widgets. The expression layer, fusevm lowering, the full jq/xpath/css/yq query surface, the web target, actors, and the package manager arrive across later milestones. 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 lands in stages. The table reflects the current tree; everything past M0 is specified in SPEC.md and not yet built.

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 + widgets (expanding)ImplementedSource query verbs — in, match/grep, reject/grepv, field N/field NAME, count, rate, tally — over line and JSON streams (in.json, nested key paths via serde_json); per-widget derived data rendering into gauge/bars/histo (src/query.rs). Surface grows through later M2 sub-milestones.
M2+ — Presets / imports / richer queryPlannedModules + preset dashboards; CSV/XML/HTML/YAML/TOML extraction, where(pred), sort / group / uniq.
M3 — Interactive controls + outPlannedFilter / facet / slider controls that megafilter/map the passthrough.
M4 — Expect + eventsPlannedStream reactions (expect) and Tk-style bind events.
M5 — Web targetPlannedServed zgui page + WebSocket live update (-t web).
M6 — ActorsPlannedAkka-style actors, pools, ask/tell, stream fan-out via a pool.
M7 — Package manager + registryPlannedScript + native packages, arb install/add/publish, the shared-dashboard ecosystem.
M8 — LSP / DAPPlannedEditor tooling over stdio JSON-RPC (shape reused from siblings).

Architecture (target)

arb is designed as a fusevm frontend: the spec is meant to lower to fusevm::Chunk bytecode and run on the shared VM + Cranelift JIT, with ratatui / zgui / query / actor behaviour served by an extension-op host. Today the M1/M2 tree is a direct interpreter — the Tcl-flavored reader (src/lexer.rs, src/parser.rs, src/ast.rs) builds a Spec (src/spec.rs) that src/tui.rs renders, with source bodies evaluated by the query pipeline (src/query.rs) over the live stream (src/stream.rs). Current deps are ratatui, clap, and regex; the fusevm lowering and the modules marked (planned) below arrive in later milestones.

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/query.rs     source query pipeline          (present)
src/stream.rs    live stream state              (present)
src/tui.rs       ratatui backend                (present)
src/compiler.rs  AST -> fusevm::Chunk           (planned lowering)
src/host.rs      extension ops: ratatui/zgui/query/actors  (planned)
src/web.rs       zgui codegen + WS server       (planned, feature: web)
src/actor.rs     Akka-style runtime             (planned, feature: actors)
src/module.rs    import / resolution            (planned)
src/pkg.rs       package manager (arb.toml)     (planned)
src/cache.rs     rkyv bytecode cache ~/.arb/    (planned)
src/lsp.rs src/dap.rs   stdio JSON-RPC          (planned)

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