Skip to content

feat(bindings): expose sqlite builtin to Python and JS bindings#1510

Merged
chaliy merged 2 commits intomainfrom
claude/sqlite-bindings-B
May 2, 2026
Merged

feat(bindings): expose sqlite builtin to Python and JS bindings#1510
chaliy merged 2 commits intomainfrom
claude/sqlite-bindings-B

Conversation

@chaliy
Copy link
Copy Markdown
Contributor

@chaliy chaliy commented May 2, 2026

Summary

Expose the embedded SQLite builtin (#1502) to the Python (PyO3) and JavaScript (NAPI) SDKs by mirroring the existing python=True opt-in pattern. PR B of the post-launch plan.

Why

After #1502 / #1507, the builtin only reached users via the Rust API or the bashkit CLI. Anyone consuming bashkit through the language bindings (the primary surface for LLM agent integrations) had to hand-roll Bash::builder().sqlite() or shell out to the CLI. This closes the gap.

How

Python (bashkit-python)

  • Bash.__init__(..., sqlite: bool = False) and the matching from_snapshot static constructor accept the new keyword.
  • New apply_sqlite_config() helper, called from both new() and the reset() rebuild path. Sets up the builtin and injects BASHKIT_ALLOW_INPROCESS_SQLITE=1 so the runtime gate is satisfied transparently — same shape as apply_python_config().
  • The flag survives across reset() (covered by test_sqlite_survives_reset).
  • _bashkit.pyi updated with the keyword + docstring describing the default policy (4 MiB script cap, 256 MiB DB cap, 30 s deadline, ATTACH and resource-PRAGMAs rejected).

JavaScript (bashkit-js)

  • BashOptions.sqlite?: boolean added to the public option struct.
  • default_opts() includes it; shared_state_from_opts() threads it through SharedState.
  • Builder hook applies .sqlite() + env opt-in symmetrically to the existing python branch.
  • .d.ts regenerated by NAPI from the struct (no manual stub).

Cargo features

Both bashkit-python/Cargo.toml and bashkit-js/Cargo.toml now include sqlite in the bashkit feature list. Neither had previously enabled it, so the binding now actually pulls in turso when built.

Tests

  • tests/test_sqlite.py (Python, 12 cases): opt-in gate, basic queries (CRUD, headers, CSV, JSON), VFS persistence, dot-commands (.tables, .dump/.read round-trip), security policy surfacing (ATTACH/DETACH, PRAGMA deny), reset preservation.
  • __test__/runtime-compat/sqlite.test.mjs (JS, 8 cases): same shape from JS.
  • All previously-green tests still green: 2289 lib + 95 CLI.
  • ruff check and ruff format --check clean.
  • cargo vet --locked succeeds.

Test plan

  • cargo build -p bashkit-python → ok
  • cargo build -p bashkit-js → ok
  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --features sqlite -p bashkit --lib → 2289 passed
  • cargo test -p bashkit-cli → 95 passed
  • cargo vet --locked → succeeds
  • ruff check crates/bashkit-python && ruff format --check crates/bashkit-python → clean
  • CI green (Python + JS suites)

Generated by Claude Code

PR B of the post-launch follow-up plan (#1502). Mirrors the existing
`python=True` opt-in pattern so SDK users can reach the Turso-backed
SQLite builtin without dropping down to bash builders.

### Python (PyO3)

- `Bash(sqlite=True)` and `Bash.from_snapshot(..., sqlite=True)` now
  register the builtin and inject `BASHKIT_ALLOW_INPROCESS_SQLITE=1` so
  the runtime gate is satisfied transparently.
- New `apply_sqlite_config()` helper centralises the wiring for both
  `new()` and `reset()`, mirroring `apply_python_config()`.
- The `sqlite` flag is preserved on the struct and reapplied across
  `reset()` (regression-tested).
- `_bashkit.pyi` updated with the new keyword and a docstring entry
  describing the default policy (script/DB caps, deadline, ATTACH and
  resource-PRAGMAs rejected).

### JavaScript / TypeScript (NAPI)

- `BashOptions.sqlite?: boolean` added to the public option struct;
  `default_opts()` now includes it, and `shared_state_from_opts()`
  threads it through `SharedState`.
- The builder hook applies `.sqlite()` and the env opt-in symmetrically
  to the existing python branch.
- The `.d.ts` is regenerated by NAPI from the struct, no manual stub
  edits.

### Tests

- `crates/bashkit-python/tests/test_sqlite.py`: 12 cases covering
  opt-in gate, basic queries, output modes, VFS persistence,
  dot-commands, ATTACH/PRAGMA policy surfacing, and reset preservation.
- `crates/bashkit-js/__test__/runtime-compat/sqlite.test.mjs`: 8 cases
  covering the same surface from JS.
- All previously-green tests still green: 2289 lib + 95 CLI + sqlite
  module tests.
- `cargo vet --locked` succeeds (no new transitive deps; sqlite already
  in the audit set from the original PR).

### Cargo features

- `bashkit-python` and `bashkit-js` now include `sqlite` in the
  `bashkit` feature list. Neither binding had previously enabled it.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 2, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit e04f17c Commit Preview URL

Branch Preview URL
May 02 2026, 05:11 PM

The JS binding wraps NAPI's `BashOptions` with a hand-written
`toNativeOptions()` mapper in `wrapper.ts` that explicitly enumerates
every field forwarded to native code. The previous commit added
`sqlite?: boolean` to the public `BashOptions` and to the Rust struct,
but forgot to thread the field through `toNativeOptions()` — so JS
callers passing `{ sqlite: true }` had the flag silently dropped.

Both binding tests caught this in CI: `sqlite: command not found` on
node 20/22/24/latest and bun latest/canary, because the constructor
options never reached Rust.

Add `sqlite: options?.sqlite` to the mapper and a corresponding doc'd
field on the `BashOptions` interface in wrapper.ts. Verified locally:

  cargo run --... build:cjs && build:ts
  node --test __test__/runtime-compat/sqlite.test.mjs
  → 9 pass, 0 fail
  bun test __test__/runtime-compat/sqlite.test.mjs
  → 9 pass, 0 fail
@chaliy chaliy merged commit bca424f into main May 2, 2026
34 checks passed
@chaliy chaliy deleted the claude/sqlite-bindings-B branch May 2, 2026 17:28
@codecov
Copy link
Copy Markdown

codecov Bot commented May 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant