Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 52 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,59 @@

## Unreleased

### Fixed
## [0.14.4] - 2026-07-27

### Highlights

- **Python wheels now use CPython's stable ABI.** One `cp39-abi3` wheel per
platform supports every Python version from 3.9 onward, reducing native
release artifacts from 42 wheels (~500 MiB) to 7 (~85 MiB). This prevents
the partial PyPI publications that left 0.14.2 unavailable on Python
3.12–3.14 ([#2190](https://github.com/everruns/bashkit/pull/2190)).
- **Browser files can persist across sessions.** The browser example stores
its virtual filesystem in browser storage, tolerates environments where
storage access is blocked, and rejects timeout guarantees that the
single-threaded WebAssembly runtime cannot enforce
([#2192](https://github.com/everruns/bashkit/pull/2192),
[#2211](https://github.com/everruns/bashkit/pull/2211),
[#2213](https://github.com/everruns/bashkit/pull/2213)).
- **Async filesystem operations no longer block current-thread runtimes.**
RealFs path resolution and metadata operations now use asynchronous host
filesystem I/O. Async embedders should use `RealFs::open`; the blocking
`RealFs::new` constructor is deprecated
([#2205](https://github.com/everruns/bashkit/pull/2205)).

### What's Changed

- RealFs path resolution and metadata updates no longer perform synchronous
host filesystem I/O inside async backend methods, preventing stalls and
deadlocks on current-thread Tokio runtimes. Async embedders should use the
new `RealFs::open`; the blocking `RealFs::new` constructor is deprecated.
* chore(deps): bump postcss to 8.5.23 to close path-traversal advisory ([#2215](https://github.com/everruns/bashkit/pull/2215)) by @chaliy
* fix(examples): pin browser npm dependencies ([#2214](https://github.com/everruns/bashkit/pull/2214)) by @chaliy
* fix(wasm): tolerate blocked browser storage ([#2213](https://github.com/everruns/bashkit/pull/2213)) by @chaliy
* fix(release): remove invalid web workflow dispatch ([#2212](https://github.com/everruns/bashkit/pull/2212)) by @chaliy
* fix(wasm): reject unenforceable timeouts ([#2211](https://github.com/everruns/bashkit/pull/2211)) by @chaliy
* fix(python): stop teardown test flaking on unrelated thread reaps ([#2210](https://github.com/everruns/bashkit/pull/2210)) by @chaliy
* chore(knowledge): group concepts into domain subfolders ([#2209](https://github.com/everruns/bashkit/pull/2209)) by @chaliy
* chore(knowledge): make the knowledge bundle actually OKF v0.2 conformant ([#2206](https://github.com/everruns/bashkit/pull/2206)) by @chaliy
* fix(realfs): avoid blocking async runtimes ([#2205](https://github.com/everruns/bashkit/pull/2205)) by @chaliy
* chore(deps): bump the rust-dependencies group across 1 directory with 7 updates ([#2204](https://github.com/everruns/bashkit/pull/2204)) by @dependabot
* chore(ci): bump the github-actions group across 1 directory with 3 updates ([#2203](https://github.com/everruns/bashkit/pull/2203)) by @dependabot
* chore(knowledge): migrate specs to OKF ([#2202](https://github.com/everruns/bashkit/pull/2202)) by @chaliy
* chore(deps): move monty to crates.io 0.0.19 ([#2201](https://github.com/everruns/bashkit/pull/2201)) by @chaliy
* chore(deps): upgrade embedded runtimes ([#2200](https://github.com/everruns/bashkit/pull/2200)) by @chaliy
* test(fuzz): constrain arithmetic expressions ([#2199](https://github.com/everruns/bashkit/pull/2199)) by @chaliy
* fix(fs): block namespace node copy destinations ([#2198](https://github.com/everruns/bashkit/pull/2198)) by @chaliy
* fix(wasm): reject async custom builtins before executeSync invocation ([#2197](https://github.com/everruns/bashkit/pull/2197)) by @chaliy
* fix(deps): resolve npm security advisories ([#2195](https://github.com/everruns/bashkit/pull/2195)) by @chaliy
* chore(deps): bump the rust-dependencies group with 14 updates ([#2194](https://github.com/everruns/bashkit/pull/2194)) by @dependabot
* chore(ci): bump the github-actions group with 2 updates ([#2193](https://github.com/everruns/bashkit/pull/2193)) by @dependabot
* feat(wasm): persist browser example files ([#2192](https://github.com/everruns/bashkit/pull/2192)) by @chaliy
* docs: per-target Get started flow + linkable heading anchors ([#2191](https://github.com/everruns/bashkit/pull/2191)) by @chaliy
* chore(python): build abi3 wheels to cut PyPI storage ~6x ([#2190](https://github.com/everruns/bashkit/pull/2190)) by @chaliy
* Revert "build(python): ship abi3 stable-ABI wheels (#2187)" ([#2189](https://github.com/everruns/bashkit/pull/2189)) by @chaliy
* docs: add Targets & bindings page with a live in-browser bash terminal ([#2188](https://github.com/everruns/bashkit/pull/2188)) by @chaliy
* build(python): ship abi3 stable-ABI wheels ([#2187](https://github.com/everruns/bashkit/pull/2187)) by @chaliy
* docs(examples): refresh browser screenshot for the bashkit-wasm rename ([#2186](https://github.com/everruns/bashkit/pull/2186)) by @chaliy

**Full Changelog**: https://github.com/everruns/bashkit/compare/v0.14.3...v0.14.4

## [0.14.3] - 2026-07-18

Expand Down
16 changes: 8 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ resolver = "2"
members = ["crates/*"]

[workspace.package]
version = "0.14.3"
version = "0.14.4"
edition = "2024"
license = "MIT"
authors = ["Mykhailo Chalyi <mike@chaliy.name>", "Everruns"]
Expand Down
2 changes: 1 addition & 1 deletion crates/bashkit-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interactive = ["dep:rustyline", "dep:terminal_size", "dep:signal-hook"]
# The CLI drives the `Bash` interpreter directly and never touches the LLM
# `BashTool` wrapper, so it opts out of the default `bash_tool` feature to
# avoid pulling in tower / futures-core.
bashkit = { path = "../bashkit", version = "0.14.3", default-features = false, features = ["http_client", "git", "jq"] }
bashkit = { path = "../bashkit", version = "0.14.4", default-features = false, features = ["http_client", "git", "jq"] }
tokio = { workspace = true, features = ["macros", "net", "rt", "rt-multi-thread", "time"] }
clap.workspace = true
anyhow.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/bashkit-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@everruns/bashkit",
"version": "0.14.3",
"version": "0.14.4",
"description": "Sandboxed bash interpreter for JavaScript/TypeScript",
"packageManager": "pnpm@10.33.0",
"main": "wrapper.js",
Expand Down
2 changes: 1 addition & 1 deletion crates/bashkit-wasm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@everruns/bashkit-wasm",
"version": "0.14.3",
"version": "0.14.4",
"description": "Sandboxed bash interpreter for the browser (WebAssembly). Single-threaded — no SharedArrayBuffer, no COOP/COEP headers.",
"type": "module",
"main": "index.js",
Expand Down
77 changes: 36 additions & 41 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -341,44 +341,8 @@ release-check:
# Check nightly CI jobs (last 3 runs must be green)
just check-nightly

# Match publish.yml locally: strip git-only publish blockers, dry-run, restore.
TMPDIR=$(mktemp -d)
LOCKFILE=Cargo.lock
BASHKIT_TOML=crates/bashkit/Cargo.toml
CLI_TOML=crates/bashkit-cli/Cargo.toml
JS_TOML=crates/bashkit-js/Cargo.toml
PY_TOML=crates/bashkit-python/Cargo.toml
cp "$LOCKFILE" "$TMPDIR/Cargo.lock"
cp "$BASHKIT_TOML" "$TMPDIR/bashkit.Cargo.toml"
cp "$CLI_TOML" "$TMPDIR/bashkit-cli.Cargo.toml"
cp "$JS_TOML" "$TMPDIR/bashkit-js.Cargo.toml"
cp "$PY_TOML" "$TMPDIR/bashkit-python.Cargo.toml"
trap 'cp "$TMPDIR/Cargo.lock" "$LOCKFILE"; \
cp "$TMPDIR/bashkit.Cargo.toml" "$BASHKIT_TOML"; \
cp "$TMPDIR/bashkit-cli.Cargo.toml" "$CLI_TOML"; \
cp "$TMPDIR/bashkit-js.Cargo.toml" "$JS_TOML"; \
cp "$TMPDIR/bashkit-python.Cargo.toml" "$PY_TOML"; \
rm -rf "$TMPDIR"' EXIT
perli() {
perl -0pi.bak -e "$1" "$2"
rm -f "$2.bak"
}

# --- bashkit core: remove monty dep and python feature ---
perli 's/^monty = .*?\n//m' "$BASHKIT_TOML"
perli 's/^python = \["dep:monty"\]\n//m' "$BASHKIT_TOML"
perli 's/\n\[\[example\]\]\nname = "python_scripts"\nrequired-features = \["python"\]\n//g' "$BASHKIT_TOML"
perli 's/\n\[\[example\]\]\nname = "python_external_functions"\nrequired-features = \["python"\]\n//g' "$BASHKIT_TOML"

# --- bashkit-cli: remove python feature ---
perli 's/^python = \["bashkit\/python"\]\n//m' "$CLI_TOML"
perli 's/, "python"//g; s/"python", //g; s/\["python"\]/[]/g' "$CLI_TOML"

# --- bashkit-js/bashkit-python: remove python from features list ---
perli 's/, "python"//g; s/"python", //g' "$JS_TOML"
perli 's/, "python"//g; s/"python", //g' "$PY_TOML"

# Dry-run publish
# Monty is a registry dependency, so verify the exact package that CI
# publishes. Rewriting manifests here can hide real packaging failures.
echo ""
echo "Dry-run publish bashkit..."
cargo publish -p bashkit --dry-run --allow-dirty
Expand All @@ -387,9 +351,40 @@ release-check:
echo "Dry-run publish bashkit-cli..."
# bashkit-cli verifies against the registry package of bashkit.
# Before the matching bashkit release is published, local dry-run cannot
# compile that packaged dependency graph. The real publish workflow keeps
# verification enabled after bashkit is live on crates.io.
cargo publish -p bashkit-cli --dry-run --allow-dirty --no-verify
# resolve that package. Package a disposable workspace against the latest
# published core as a structural proxy. The real workflow publishes and
# verifies the matching core before publishing the CLI.
CLI_VERIFY_ROOT=$(mktemp -d)
trap 'rm -rf "$CLI_VERIFY_ROOT"' EXIT
rsync -a \
--exclude .git \
--exclude node_modules \
--exclude target \
./ "$CLI_VERIFY_ROOT/workspace/"
LATEST_CORE=$(cargo search bashkit --limit 1 | sed -n 's/^bashkit = "\([^"]*\)".*/\1/p')
if [ -z "$LATEST_CORE" ]; then
echo "Error: could not determine latest published bashkit version"
exit 1
fi
WORKSPACE_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
CLI_TOML="$CLI_VERIFY_ROOT/workspace/crates/bashkit-cli/Cargo.toml"
sed -i.bak \
"s/version = \"$WORKSPACE_VERSION\"/version = \"$LATEST_CORE\"/" \
"$CLI_TOML"
rm "$CLI_TOML.bak"
# The latest published core predates Monty's crates.io publication and
# therefore lacks the Python feature. The exact new core package dry-run
# above validates that feature; omit it only from this CLI structure proxy.
perl -0pi.bak -e \
's/^python = \["bashkit\/python"\]\n//m; s/"python", //g; s/, "python"//g' \
"$CLI_TOML"
rm "$CLI_TOML.bak"
cargo publish \
--manifest-path "$CLI_VERIFY_ROOT/workspace/Cargo.toml" \
-p bashkit-cli \
--dry-run \
--allow-dirty \
--no-verify

echo ""
echo "All release checks passed!"
Expand Down