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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ serde_json = "1"
# JSON processing (jq) - verified embeddable
jaq-core = "2"
jaq-std = "2"
jaq-json = { version = "1", features = ["serde_json"] }

# Text search (grep) - verified supports search_slice() for in-memory
grep = "0.3"
Expand Down
105 changes: 95 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,108 @@
# rust-template
# BashKit

<!-- TODO: Add project description -->
Sandboxed bash interpreter for multi-tenant environments. Written in Rust.

## Overview
## Features

<!-- TODO: Add overview -->
- **Sandboxed execution** - No real filesystem access by default
- **Virtual filesystem** - InMemoryFs, OverlayFs, MountableFs
- **Resource limits** - Command count, loop iterations, function depth
- **Network allowlist** - Control HTTP access per-domain
- **MCP server mode** - Model Context Protocol integration
- **Async-first** - Built on tokio

## Quick Start

```rust
use bashkit::Bash;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut bash = Bash::new();
let result = bash.exec("echo hello world").await?;
println!("{}", result.stdout); // "hello world\n"
Ok(())
}
```

## Built-in Commands

| Category | Commands |
|----------|----------|
| Core | `echo`, `printf`, `cat`, `read` |
| Navigation | `cd`, `pwd` |
| Flow control | `true`, `false`, `exit`, `test`, `[` |
| Variables | `export`, `set`, `unset`, `local`, `source` |
| Text processing | `grep`, `sed`, `awk`, `jq` |

## Shell Features

- Variables and parameter expansion (`$VAR`, `${VAR:-default}`, `${#VAR}`)
- Command substitution (`$(cmd)`)
- Arithmetic expansion (`$((1 + 2))`)
- Pipelines and redirections (`|`, `>`, `>>`, `<`, `<<<`)
- Control flow (`if`/`elif`/`else`, `for`, `while`, `case`)
- Functions (POSIX and bash-style)
- Arrays (`arr=(a b c)`, `${arr[@]}`, `${#arr[@]}`)
- Glob expansion (`*`, `?`)
- Here documents (`<<EOF`)

## Configuration

```rust
use bashkit::{Bash, ExecutionLimits, InMemoryFs};
use std::sync::Arc;

let limits = ExecutionLimits::new()
.max_commands(1000)
.max_loop_iterations(10000)
.max_function_depth(100);

let mut bash = Bash::builder()
.fs(Arc::new(InMemoryFs::new()))
.env("HOME", "/home/user")
.cwd("/home/user")
.limits(limits)
.build();
```

## Virtual Filesystem

```rust
use bashkit::{InMemoryFs, OverlayFs, MountableFs, FileSystem};
use std::sync::Arc;

// Layer filesystems
let base = Arc::new(InMemoryFs::new());
let overlay = Arc::new(OverlayFs::new(base));

// Mount points
let mut mountable = MountableFs::new(Arc::new(InMemoryFs::new()));
mountable.mount("/data", Arc::new(InMemoryFs::new()));
```

## CLI Usage

```bash
cargo build
cargo run
# Run a script
bashkit-cli run script.sh

# Interactive REPL
bashkit-cli repl

# MCP server mode
bashkit-cli mcp
```

## Documentation
## Development

- [AGENTS.md](./AGENTS.md) - Agent instructions
- [CONTRIBUTING.md](./CONTRIBUTING.md) - Contribution guide
```bash
just build # Build project
just test # Run tests
just check # fmt + clippy + test
just pre-pr # Pre-PR checks
```

## License

<!-- TODO: Add license -->
MIT
5 changes: 5 additions & 0 deletions crates/bashkit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ reqwest = { workspace = true, optional = true }
# URL parsing
url = "2"

# JSON processing (jq)
jaq-core = { workspace = true }
jaq-std = { workspace = true }
jaq-json = { workspace = true }

[features]
default = []
network = ["reqwest"]
Expand Down
Loading