Changelog
View SourceAll notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.4.0 (2026-09-28)
⚠ BREAKING CHANGES
- JustBash.Fs and JustBash.Fs.InMemoryFs are replaced by JustBash.FS / JustBash.FS.Memory with vfs-shaped returns ({:ok, payload, fs} on reads, %VFS.Error{} on failure, %VFS.Stat{} from stat). Bash-level script behavior is unchanged.
Features
- add JustBash.CLI for namespaced subcommand tools (#39) (2761adf)
- add put_context/3 and get_context/3 accessors (#41) (2c6e6b7)
- cli: address consumer feedback from issue #38 (#43) (7d84244)
- replace the filesystem layer with the vfs library (#44) (1da1db8)
Bug Fixes
- /dev/null exists as a filesystem node so operands agree with redirects (#78) (#93) (8619ada)
- a CLI flag rejects unknown spec keys and accepts extra long spellings (#71) (83af599)
- a command whose redirect fails does not run at all (#60) (025673c)
- a flag a command does not implement is an error, not a filename (#72) (9aab27a)
- a trailing slash on a destination requires a directory instead of overwriting the file it names (#75) (5de39ef)
- awk's empty for(;;) condition is true, matching gawk (#87) (ca5c918)
- bound ${v//pat/rep} so global replace cannot OOM (#97) (f2beeb9)
- bound value size so doubling cannot blow past max_wall_ms (#85) (55c0f50), closes #77
- cp into a directory, and make cp -r actually copy (#57) (7d73837)
- date implements %F and -I instead of emitting them literally (#63) (274e86b)
- date rejects unknown arguments instead of returning today at exit 0 (#66) (fd2bb2c)
- empty path operands are ENOENT, not the current directory (#95) (2e73917)
- exec/2 returns a shell result instead of raising, and always terminates (#73) (3b9be0d)
- find and jq honour
--as end-of-options (#90) (#98) (0077d63) - grep BRE alternation, missing-path exit code, and flag-level did-you-mean (#84) (3d2c625)
- head default line count no longer emits a trailing blank line (#91) (1bcda6b)
- honour
--as end-of-options for file-operand commands (#89) (b5477c3) - mkdir and rm report backend errors instead of crashing the exec (#48) (dffd5dd)
- printf %b support and no-progress guard against format-recycle hangs (#50) (56c74b8)
- replace retired earmark runtime dependency with mdex (#55) (ce86847), closes #54
- shasum -c and sha256sum -c read checksums from stdin (#88) (cdddddc)
- Special table owns readdir merge and write-redirect paths (#99) (05a26b2)
- tac does not invent a newline on an unterminated last record (#92) (6c92a44)
- writing through a regular file is ENOTDIR, not unreachable state (#56) (1633cdc)
Miscellaneous Chores
- release 0.4.0 (3abac04)
0.3.0 (2026-04-14)
Features
- add context option to justbash struct for custom commands (#34) (8824fd9)
- add xxd/od, curl flags, grep -P, awk crash guard (#32) (4afdb3b)
- add production resource limits and execution stats (#28) (9c7a36d)
- add missing command flags, stdin support, and bash comparison fixtures (#31) (67de3b0)
- replace NimbleParsec lexer with hand-written state machine (#30) (bc05d36)
- add telemetry instrumentation for script execution (#29) (b8cac23)
Bug Fixes
- jq parser failing to resolve builtin function names to atoms (144cbe8)
0.2.0 (2026-03-23)
Features
- add 12 new evals covering uncovered commands and shell features (2c21f75)
- add custom command eval with KV store (840ba00)
- add eval system and fix 5 bugs exposed by LLM agent evals (39e4637)
- expand evals to 28 tasks and fix 8 additional bugs (5ba37c5)
- major expansion - 15 new commands, jq overhaul, test infrastructure (a5efb73)
- test infrastructure, new commands, jq overhaul (13749d2)
Bug Fixes
- 8 AWK bugs, jq -e exit status, declare -A keys, printf redirect parsing (cb57e64)
- capture bash state between exec calls in README example (09b2039)
- correct GitHub URLs in CHANGELOG (a4cf791)
- correct GitHub URLs in CHANGELOG (5b29c7e)
- heredoc in compound commands, assoc array subscripts, which/type builtins, jq @tsv (99aab44)
- implement AWK field assignment ($N = value) with $0 reconstruction (e760cad)
- read IFS splitting, wc/head/tail multi-file, and improve eval robustness (7d96af7)
- remove deprecated package-name from release-please workflow (d1d7ab7)
- tests: use variable instead of module attribute for spec tests (#18) (f583911)
Unreleased
Added
mix bash_fixtures.gen printfenumerates a printf conversion × flag/width/precision matrix (printf_matrix) — #70 item 2mix bash_fixtures.gen testenumerates atest/[operator × revealing-shape matrix (test_matrix) — #70 item 2mix bash_fixtures.gen varopenumerates a${var op word}parameter-expansion matrix (varop_matrix) — #70 item 2mix bash_fixtures.gen flagsenumerates a Registry-wide unknown-flag probe (flags_matrix) — #70 item 2mix bash_fixtures.gen setoenumerates the POSIX/bashset -o/+oname alphabet (seto_matrix) — #70 item 2
Bug Fixes
${v//pat/rep}/${v/pat/rep}refuse before allocating a result that would exceed:max_value_bytes(#86)- empty-string path operands are
ENOENT, not the current directory (#79) - honour
--as end-of-options for file-operand commands (#83) - find and jq honour
--as end-of-options:find -- -foois a path,jq -- .is the filter (#90) - head default line count no longer emits a trailing blank line (#80)
- tac no longer invents a newline on an unterminated last record (#82)
/dev/nullexists as a filesystem node, so operands agree with redirects (#78)FS.readdir/2only uniq-sorts directories that contribute special children, and write redirects to/dev/./nullskip the file-size cap (#94)
0.1.0 - 2026-01-11
Added
- Initial release
- In-memory virtual filesystem (
JustBash.Fs.InMemoryFs) - Bash lexer and recursive descent parser
- Variable expansion:
$VAR,${VAR},${VAR:-default},${VAR:=default},${VAR:+alt},${#VAR},${VAR:start:len},${VAR#pattern},${VAR%pattern},${VAR/old/new},${VAR^^},${VAR,,} - Command substitution:
$(cmd)and backticks - Arithmetic expansion:
$((expr))with full operator support including**,?:, hex, binary - Control flow:
if/elif/else/fi,for x in ...; do; done,while/until,case/esac - Logical operators:
&&,||,!with short-circuit evaluation - Pipes with stdin/stdout flow
- Redirections:
>,>>,2>,&>,<,<<<, heredocs - Brace expansion:
{a,b,c},{1..5},{a..z} - Arrays:
arr=(...),${arr[0]},${arr[@]},${#arr[@]} - Functions with local variables
- Extended test command:
[[ ]]with regex support
Commands
File operations:
cat,ls,cp,mv,rm,mkdir,touch,lnfind,stat,du,tree,file,readlink
Text processing:
grep,sed,awk(full implementations)sort,uniq,head,tail,wc,cut,trrev,tac,nl,fold,paste,comm,diff,expand
Data tools:
jq(comprehensive JSON processor)curl(HTTP client with network allowlists)markdown/md(Markdown to HTML)base64,md5sum
Shell builtins:
echo,printf,pwd,cd,export,unsettest,[,[[,true,false,:set(shell options:-e,-u,-o pipefail)source,.,read,exit,returnlocal,declare,typesetbreak,continue,shift,getopts,trap
Utilities:
seq,date,sleep,basename,dirnamewhich,env,printenv,hostnamexargs,tee