Context
Node bindings expose VFS operations directly on the Bash class (bash.readFile(), bash.writeFile(), bash.ls(), bash.glob(), etc.) for ergonomic access. Python requires an extra indirection: bash.fs().read_file().
Both patterns should be available in Python: direct methods for convenience, fs() accessor for advanced use.
This is part of the Python ↔ Node binding parity effort (Phase 1 — API Parity).
What to implement
Add 13 delegate methods to PyBash and PyBashTool in crates/bashkit-python/src/lib.rs that forward to the internal FileSystem:
bash.read_file(path: str) -> str
bash.write_file(path: str, content: str) -> None
bash.append_file(path: str, content: str) -> None
bash.mkdir(path: str, recursive: bool = False) -> None
bash.exists(path: str) -> bool
bash.remove(path: str, recursive: bool = False) -> None
bash.stat(path: str) -> dict
bash.chmod(path: str, mode: int) -> None
bash.symlink(target: str, link: str) -> None
bash.read_link(path: str) -> str
bash.read_dir(path: str) -> list[dict]
bash.ls(path: str = ".") -> list[str] # simple name list
bash.glob(pattern: str) -> list[str] # safe glob matching
Important design notes
- These should return
str (not bytes like FileSystem.read_file()), matching Node's behavior and the common case
ls() returns a simple list[str] of names (like Node's ls()), not the full metadata that read_dir() returns
glob() must use safe glob only (no arbitrary shell expansion)
- The
fs() accessor remains available for users who need bytes-level access or the FileSystem static constructors
- Methods should be added to both
PyBash AND PyBashTool
Node reference
In crates/bashkit-js/src/lib.rs and wrapper.ts, Node implements these as methods on the Bash class that delegate to the internal interpreter's VFS.
Acceptance criteria
Context
Node bindings expose VFS operations directly on the
Bashclass (bash.readFile(),bash.writeFile(),bash.ls(),bash.glob(), etc.) for ergonomic access. Python requires an extra indirection:bash.fs().read_file().Both patterns should be available in Python: direct methods for convenience,
fs()accessor for advanced use.This is part of the Python ↔ Node binding parity effort (Phase 1 — API Parity).
What to implement
Add 13 delegate methods to
PyBashandPyBashToolincrates/bashkit-python/src/lib.rsthat forward to the internalFileSystem:Important design notes
str(notbyteslikeFileSystem.read_file()), matching Node's behavior and the common casels()returns a simplelist[str]of names (like Node'sls()), not the full metadata thatread_dir()returnsglob()must use safe glob only (no arbitrary shell expansion)fs()accessor remains available for users who needbytes-level access or theFileSystemstatic constructorsPyBashANDPyBashToolNode reference
In
crates/bashkit-js/src/lib.rsandwrapper.ts, Node implements these as methods on theBashclass that delegate to the internal interpreter's VFS.Acceptance criteria
PyBashclassPyBashToolclassread_file()returnsstr(UTF-8 decoded), raises on binary/non-UTF-8write_file()andappend_file()acceptstrls()returnslist[str]of entry names in the given directoryglob()returnslist[str]of matching paths (safe glob only)stat()returns dict with keys:file_type,size,mode,modified,createdread_dir()returnslist[dict]withnameand metadata per entryreset()(VFS is cleared)bash.execute_sync("echo hi > /tmp/f")thenbash.read_file("/tmp/f"))_bashkit.pyiwith docstringscargo clippyandruff checkpass