Expand description
bashlite — a tiny, total, sandboxed shell that scripts the platform’s
filesystem in one pass (the cost unlock: a multi-step fs chore collapses
from N LLM rounds to ONE execute_script tool call). Native-testable core
over a bashlite::BashHost trait. See src/bashlite/ + design/bashlite.md.
bashlite — a tiny, deterministic, TOTAL shell that scripts the platform’s
filesystem in ONE pass (see design/bashlite.md).
The cost unlock: an agent doing a multi-step fs chore today burns one LLM
round (full context + ~70 tool schemas) per step. bashlite collapses the
chore into a single execute_script tool call — the platform runs the whole
script locally and only the final stdout returns to the model.
Shape (mirrors rustlite/): lexer → parser → eval over a [BashHost] trait,
so the whole interpreter is native-testable (cargo test) and the
browser/CLI just supply the host. NO eval, NO process spawning, NO network.
§v1 language subset (this module)
- Variables:
x=value,x=$(cmd);$x/${x}interpolation;$?exit. - Pipes:
a | b | c(stdout → stdin). - Short-circuit chains:
a && b(runbiffaexited 0),a || b(iff nonzero); mixedcond && a || bis the ternary (skip, not break). - Control flow:
if/elif/else/fi,for NAME in …; do … done,while …; do … done. - Tests:
[ … ]/test …(string=/!=/-z/-n, int-eq/-lt/…, file-e/-f/-d PATH). - Command substitution:
$(…)(nested, subshell vars, shared fuel). - Builtins (fs):
echo,cd,pwd,ls,cat,grep,find,wc,head/tail(first/last N stdin lines),mkdir,write/create(CREATE-only),true/false. - Composition (
run/source/.): execute another.blscript in a nested evaluator (shared fs + fuel) — a script is a composition of scripts. FRACTAL: the sub-script can itselfrunmore, bounded by the shared fuel. - Host extension: a [
BashHost] adds commands by overridingrun_builtin(e.g. thelh-*platform reads in [platform]) — the evaluator routes every non-control command through it, so “localharnesslite” is just more commands. for NAME in $(…)FIELD-SPLITS on whitespace (the fan-out pattern).- Quoting:
'single'literal,"double"interpolating,\escape. - BOUNDED: a fuel budget caps total commands + loop iterations so a
while true(orrun-recursion) can’t hang; output is byte-capped.
§Deferred to v2 (intentionally NOT in v1 — see design/bashlite.md)
- Value-MOVING
lh-*commands (lh-send,lh-create, …) + the dry-run-manifest confirm flow. (Read-onlylh-*ship in [platform].) break/continue/return, functions, here-docs, redirection (>/>>/<— REJECTED with a parse error, never lexed as literal args), real regex grep, file-argwc, field splitting of unquoted expansions OUTSIDEforitems, globbing, arithmetic$(( )).
Re-exports§
pub use eval::Evaluator;pub use eval::ScriptResult;pub use eval::DEFAULT_FUEL;pub use eval::MAX_OUTPUT_BYTES;pub use eval::MAX_SCRIPT_SIZE;pub use host::BashHost;pub use host::Output;
Modules§
- ast
- Script AST. Abstract syntax for bashlite — a tiny, total shell.
- builtins
- FS-only builtin commands over
crate::filesystem::Filesystem. The v1 builtin commands — fs-only, overcrate::filesystem::Filesystem. - eval
- Bounded, total evaluator.
The evaluator: walk a parsed script, expand words, run pipelines through the
BashHost, and accumulate stdout. TOTAL + BOUNDED — every loop iteration and command spends one unit of FUEL, so awhile truecan’t hang the tab (it returns a clear “fuel exhausted” error instead). - host
- The
BashHostseam +Output. The host seam:BashHostis everything the pure evaluator needs from the outside world. Eval never touches a real filesystem or clock directly — it goes through this trait, so the lexer/parser/eval run unchanged undercargo testwith an in-memory host and in the browser over OPFS. - lexer
- Shell-shaped byte lexer.
Byte-level lexer: source → [
Token]s. Shell-shaped, not Rust-shaped. - parser
- Recursive-descent parser.
Recursive-descent parser: [
Token]s → a list of [Stmt]s. - platform
- Read-only
lh-*platform commands (localharnesslite). Needswallet. localharnesslite — read-onlylh-*platform commands for bashlite. - token
- Token kinds. Token types for the bashlite lexer.
Structs§
- Bash
Error - An error from any stage (lex, parse, or a fatal runtime condition like fuel
exhaustion). A command FAILING (nonzero exit) is NOT an error — that’s a
normal
Outputwith a nonzero code that the script can branch on. Only a malformed script or a runaway guard produces aBashError.
Enums§
- Bash
Error Kind - The category of a
BashError.
Functions§
- resolve_
path - Resolve
pathagainstcwdinto a normalized sandbox path the way the fs builtins do — so a host that reads a file ITSELF (e.g.lh-publish’s source arg, beforeplatform::dispatch_write) resolves it identically. Absolutepathignorescwd;./..collapse;..clamps to root (no escape). - run
- Compile + run
sourceagainsthostwith the default fuel budget, returning the accumulated stdout/stderr/exit code. - run_
with_ fuel - Like
runbut with an explicit fuel budget (commands + loop iterations).