From 7c888f8a9c92d97f7bc9747e27999be29efee8ef Mon Sep 17 00:00:00 2001 From: Mavdol Date: Mon, 20 Apr 2026 23:20:51 +0200 Subject: [PATCH 01/10] docs: update repository links, add quick start navigation, and standardize README formatting --- README.md | 2 ++ packages/bash-mcp/README.md | 4 +--- packages/bash-types/README.md | 2 +- packages/bash-wasm/README.md | 27 ++++++++++++++++++++++++- packages/bash/README.md | 38 ++++++++++++++++++++++++++++++++++- 5 files changed, 67 insertions(+), 6 deletions(-) mode change 120000 => 100644 packages/bash-wasm/README.md mode change 120000 => 100644 packages/bash/README.md diff --git a/README.md b/README.md index 14a4c50..5239795 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ ![CI](https://github.com/capsulerun/bash/actions/workflows/ci.yml/badge.svg) +[Quick Start](#quick-start) • [How It Works](#how-it-works) • [Contributing](#contributing) + ![Example Shell](assets/example.gif) diff --git a/packages/bash-mcp/README.md b/packages/bash-mcp/README.md index 15ebdc2..a1ace8c 100644 --- a/packages/bash-mcp/README.md +++ b/packages/bash-mcp/README.md @@ -1,6 +1,4 @@ -# `Capsule` bash mcp - -[![MCP Server Release](https://github.com/capsule-run/bash/actions/workflows/mcp-integration-release.yml/badge.svg)](https://github.com/capsule-run/bash/actions/workflows/mcp-integration-release.yml) +# `Capsule` Bash MCP An MCP server that gives your AI agent the ability to run bash commands in a secure, persistent, WebAssembly-sandboxed environment. diff --git a/packages/bash-types/README.md b/packages/bash-types/README.md index 1b56d92..d9353bc 100644 --- a/packages/bash-types/README.md +++ b/packages/bash-types/README.md @@ -1,3 +1,3 @@ # @capsule-run/bash-types -Shared TypeScript types for the [`@capsule-run/bash`](https://github.com/capsule-run/bash) ecosystem. +Shared TypeScript types for the [`@capsule-run/bash`](https://github.com/capsulerun/bash) ecosystem. diff --git a/packages/bash-wasm/README.md b/packages/bash-wasm/README.md deleted file mode 120000 index fe84005..0000000 --- a/packages/bash-wasm/README.md +++ /dev/null @@ -1 +0,0 @@ -../../README.md \ No newline at end of file diff --git a/packages/bash-wasm/README.md b/packages/bash-wasm/README.md new file mode 100644 index 0000000..4e19696 --- /dev/null +++ b/packages/bash-wasm/README.md @@ -0,0 +1,26 @@ +# `Capsule` Bash WASM Runtime + +**WebAssembly runtime for `@capsule-run/bash`** + +## Install + +```bash +npm install @capsule-run/bash @capsule-run/bash-wasm +``` + +## Usage + +```typescript +import { Bash } from "@capsule-run/bash"; +import { WasmRuntime } from "@capsule-run/bash-wasm"; + +const bash = new Bash({ runtime: new WasmRuntime() }); +``` + +> `WasmRuntime` runs in Node.js only. Browser environments are not supported. + +For full documentation, visit the [GitHub repository](https://github.com/capsulerun/bash). + +## License + +Apache License 2.0. diff --git a/packages/bash/README.md b/packages/bash/README.md deleted file mode 120000 index fe84005..0000000 --- a/packages/bash/README.md +++ /dev/null @@ -1 +0,0 @@ -../../README.md \ No newline at end of file diff --git a/packages/bash/README.md b/packages/bash/README.md new file mode 100644 index 0000000..4358dd4 --- /dev/null +++ b/packages/bash/README.md @@ -0,0 +1,37 @@ +# `Capsule` Bash + +**Sandboxed bash made for agents** + +## Install + +```bash +npm install @capsule-run/bash @capsule-run/bash-wasm +``` + +## Usage + +```typescript +import { Bash } from "@capsule-run/bash"; +import { WasmRuntime } from "@capsule-run/bash-wasm"; + +const bash = new Bash({ runtime: new WasmRuntime() }); + +const result = await bash.run("mkdir src && touch src/index.ts"); + +console.log(result); +/* +{ + stdout: "Folder created ✔\nFile created ✔", + stderr: "", + diff: { created: ['src', 'src/index.ts'], modified: [], deleted: [] }, + duration: 10, + exitCode: 0, +} +*/ +``` + +For full documentation, visit the [GitHub repository](https://github.com/capsulerun/bash). + +## License + +Apache License 2.0. From 2c9f8f81fe2c4f4f6f10de17962dd8daa1f2a931 Mon Sep 17 00:00:00 2001 From: Mavdol Date: Mon, 20 Apr 2026 23:49:09 +0200 Subject: [PATCH 02/10] feat: add global error handling to executor to return failed command results on exception --- packages/bash/src/core/executor.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/bash/src/core/executor.ts b/packages/bash/src/core/executor.ts index fdc449d..8287a6d 100644 --- a/packages/bash/src/core/executor.ts +++ b/packages/bash/src/core/executor.ts @@ -73,12 +73,17 @@ export class Executor { } async execute(node: ASTNode, stdin = ''): Promise { - switch (node.type) { - case 'command': return this.executeCommand(node, stdin); - case 'pipeline': return this.executePipeline(node); - case 'and': return this.executeAnd(node); - case 'or': return this.executeOr(node); - case 'sequence': return this.executeSequence(node); + try { + switch (node.type) { + case 'command': return this.executeCommand(node, stdin); + case 'pipeline': return this.executePipeline(node); + case 'and': return this.executeAnd(node); + case 'or': return this.executeOr(node); + case 'sequence': return this.executeSequence(node); + } + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + return { stdout: '', stderr: message, exitCode: 1, durationMs: 0 }; } } From 24ff1036f0880a53e30a3f66017c617a3c03ef37 Mon Sep 17 00:00:00 2001 From: Mavdol Date: Tue, 21 Apr 2026 00:22:24 +0200 Subject: [PATCH 03/10] feat: implement lazy sandbox loading and update runtime preload return type --- README.md | 4 +++- packages/bash-types/src/runtime.ts | 2 +- packages/bash-wasm/src/runtime.ts | 6 +++++- packages/bash/src/core/bash.ts | 22 +++++++++++++++++++++- packages/bash/src/core/executor.ts | 2 +- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5239795..4dd03bc 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ![CI](https://github.com/capsulerun/bash/actions/workflows/ci.yml/badge.svg) -[Quick Start](#quick-start) • [How It Works](#how-it-works) • [Contributing](#contributing) +*[Quick Start](#quick-start)* • *[Contributing](#contributing)* ![Example Shell](assets/example.gif) @@ -62,6 +62,8 @@ See the [MCP README](packages/bash-mcp) for configuration details. ### Interactive shell +Clone the repository, then run from the project root: + ```bash pnpm -s bash-wasm-shell ``` diff --git a/packages/bash-types/src/runtime.ts b/packages/bash-types/src/runtime.ts index 31f1f98..f8e3477 100644 --- a/packages/bash-types/src/runtime.ts +++ b/packages/bash-types/src/runtime.ts @@ -10,7 +10,7 @@ export interface BaseRuntime { /** * Preload the runtime */ - preload(state: State, name?: string): Promise; + preload(state: State, name?: string): Promise; /** * Execute a code diff --git a/packages/bash-wasm/src/runtime.ts b/packages/bash-wasm/src/runtime.ts index 611a986..233875b 100644 --- a/packages/bash-wasm/src/runtime.ts +++ b/packages/bash-wasm/src/runtime.ts @@ -30,13 +30,14 @@ export class WasmRuntime implements BaseRuntime { } } - async preload(state: State, name: string = "js") { + async preload(state: State, name: string = "js"): Promise { if(name === "js") { await run({ file: this.jsSandbox, args: ["PRELOAD", JSON.stringify(state)], mounts: [`${this.hostWorkspace}::/`] }) + return true; } if(name === "python") { @@ -45,7 +46,10 @@ export class WasmRuntime implements BaseRuntime { args: ["PRELOAD", JSON.stringify(state)], mounts: [`${this.hostWorkspace}::/`] }) + return true; } + + return false; } async executeCode(state: State, code: string, language: string = "js"): Promise { diff --git a/packages/bash/src/core/bash.ts b/packages/bash/src/core/bash.ts index 66adcca..5b065cf 100644 --- a/packages/bash/src/core/bash.ts +++ b/packages/bash/src/core/bash.ts @@ -10,6 +10,9 @@ export class Bash { private parser: Parser; private executor: Executor; private customCommands: CustomCommand[]; + public isPythonSandboxReady: boolean; + public isJsSandboxReady: boolean; + public readonly stateManager: StateManager; @@ -24,13 +27,30 @@ export class Bash { this.executor = new Executor(runtime, this.customCommands, this.stateManager.state); this.filesystem.init(); + + this.isPythonSandboxReady = false; + this.isJsSandboxReady = false; } async preload(name: string = "js") { - await this.runtime.preload(this.stateManager.state, name); + const ready = await this.runtime.preload(this.stateManager.state, name); + + if (name === "js") { + this.isJsSandboxReady = ready; + } else if (name === "python") { + this.isPythonSandboxReady = ready; + } } async run(command: string): Promise { + if (!this.isJsSandboxReady) { + await this.preload("js"); + } + + if (command.includes("python") && !this.isPythonSandboxReady) { + await this.preload("python"); + } + const ast = this.parser.parse(command); return this.executor.execute(ast); } diff --git a/packages/bash/src/core/executor.ts b/packages/bash/src/core/executor.ts index 8287a6d..61aa463 100644 --- a/packages/bash/src/core/executor.ts +++ b/packages/bash/src/core/executor.ts @@ -83,7 +83,7 @@ export class Executor { } } catch (err) { const message = err instanceof Error ? err.message : String(err); - return { stdout: '', stderr: message, exitCode: 1, durationMs: 0 }; + return { stdout: '', stderr: message, exitCode: 1, state: { cwd: this.state.cwd, env: this.state.env, exitCode: 1 }, diff: { created: [], modified: [], deleted: [] }, durationMs: 0 }; } } From 44d011c171559dfbb3b84b0bf3202573ffb396e1 Mon Sep 17 00:00:00 2001 From: Mavdol Date: Tue, 21 Apr 2026 00:25:07 +0200 Subject: [PATCH 04/10] chore: bump project and package versions to 0.1.1 --- package.json | 2 +- packages/bash-mcp/package.json | 2 +- packages/bash-mcp/src/index.ts | 2 +- packages/bash-types/package.json | 2 +- packages/bash-wasm/package.json | 2 +- packages/bash/package.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 6ef8186..b20bc9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "capsulerun-bash-monorepo", - "version": "0.1.0", + "version": "0.1.1", "private": true, "description": "Sandboxed bash for agents", "license": "Apache-2.0", diff --git a/packages/bash-mcp/package.json b/packages/bash-mcp/package.json index 28f78fe..eeb6fe3 100644 --- a/packages/bash-mcp/package.json +++ b/packages/bash-mcp/package.json @@ -1,6 +1,6 @@ { "name": "@capsule-run/bash-mcp", - "version": "0.1.0", + "version": "0.1.1", "description": "MCP server exposing sandboxed bash made for agents", "type": "module", "main": "./src/index.ts", diff --git a/packages/bash-mcp/src/index.ts b/packages/bash-mcp/src/index.ts index c0bded4..8a02d71 100644 --- a/packages/bash-mcp/src/index.ts +++ b/packages/bash-mcp/src/index.ts @@ -17,7 +17,7 @@ function getSession(sessionId: string): Bash { const server = new McpServer({ name: "@capsule-run/bash-mcp", - version: "0.1.0", + version: "0.1.1", }); server.registerTool( diff --git a/packages/bash-types/package.json b/packages/bash-types/package.json index 6aa44e6..a388ba2 100644 --- a/packages/bash-types/package.json +++ b/packages/bash-types/package.json @@ -1,6 +1,6 @@ { "name": "@capsule-run/bash-types", - "version": "0.1.0", + "version": "0.1.1", "description": "", "type": "module", "homepage": "https://github.com/capsulerun/bash", diff --git a/packages/bash-wasm/package.json b/packages/bash-wasm/package.json index a3f6e70..6add6ce 100644 --- a/packages/bash-wasm/package.json +++ b/packages/bash-wasm/package.json @@ -1,6 +1,6 @@ { "name": "@capsule-run/bash-wasm", - "version": "0.1.0", + "version": "0.1.1", "description": "Sandboxed bash for agents", "type": "module", "homepage": "https://github.com/capsulerun/bash", diff --git a/packages/bash/package.json b/packages/bash/package.json index 6b37a2c..c9a145d 100644 --- a/packages/bash/package.json +++ b/packages/bash/package.json @@ -1,6 +1,6 @@ { "name": "@capsule-run/bash", - "version": "0.1.0", + "version": "0.1.1", "description": "Sandboxed bash for agents", "type": "module", "homepage": "https://github.com/capsulerun/bash", From afab3d089877e86763b55076ab9c87a30cc58425 Mon Sep 17 00:00:00 2001 From: Mavdol Date: Tue, 21 Apr 2026 00:53:55 +0200 Subject: [PATCH 05/10] docs: update README badges and navigation links --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4dd03bc..ba4b6f5 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,13 @@ **Sandboxed bash made for agents** -![CI](https://github.com/capsulerun/bash/actions/workflows/ci.yml/badge.svg) +![CI](https://img.shields.io/github/actions/workflow/status/capsulerun/bash/ci.yml?branch=main) ![Release](https://img.shields.io/github/v/release/capsulerun/bash) + + + + +**[Quick Start](#quick-start)** • **[How It Works](#how-it-works)** • **[Contributing](#contributing)** -*[Quick Start](#quick-start)* • *[Contributing](#contributing)* ![Example Shell](assets/example.gif) From 4bfbdee827102d875011512205477fbcc0a0c445 Mon Sep 17 00:00:00 2001 From: Mavdol Date: Tue, 21 Apr 2026 00:59:36 +0200 Subject: [PATCH 06/10] feat: add version input and run-name to release workflow --- .github/workflows/release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a352c71..1956e6f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,12 @@ name: Release +run-name: "Release v${{ github.event.inputs.version }}" on: workflow_dispatch: + inputs: + version: + description: 'Release version' + required: true jobs: release: From 215bb1e68a5959877a8f8f07c5bca908da062856 Mon Sep 17 00:00:00 2001 From: Mavdol Date: Tue, 21 Apr 2026 01:04:20 +0200 Subject: [PATCH 07/10] docs: remove bold formatting from README navigation links --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index ba4b6f5..8c1fbee 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,7 @@ ![CI](https://img.shields.io/github/actions/workflow/status/capsulerun/bash/ci.yml?branch=main) ![Release](https://img.shields.io/github/v/release/capsulerun/bash) - - - -**[Quick Start](#quick-start)** • **[How It Works](#how-it-works)** • **[Contributing](#contributing)** - +[Quick Start](#quick-start) • [How It Works](#how-it-works) • [Contributing](#contributing) ![Example Shell](assets/example.gif) From 9f37cce62a21aa417ebf7ec9363a4e34da2b812a Mon Sep 17 00:00:00 2001 From: Mavdol Date: Tue, 21 Apr 2026 01:07:01 +0200 Subject: [PATCH 08/10] docs: rename Quick Start to Getting Started and clarify installation instructions in README --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8c1fbee..61ef0b2 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,19 @@ ![CI](https://img.shields.io/github/actions/workflow/status/capsulerun/bash/ci.yml?branch=main) ![Release](https://img.shields.io/github/v/release/capsulerun/bash) -[Quick Start](#quick-start) • [How It Works](#how-it-works) • [Contributing](#contributing) +[Getting Started](#getting-started) • [How It Works](#how-it-works) • [Contributing](#contributing) ![Example Shell](assets/example.gif) -## Quick Start +## Getting Started ```bash -npm install @capsule-run/bash @capsule-run/bash-wasm +# Install the core bash package +npm install @capsule-run/bash + +# Install the default Wasm runtime +npm install @capsule-run/bash-wasm ``` ### TypeScript SDK From 65554d8b97a9a02fd6cb5fb09149a6fe2f7b6598 Mon Sep 17 00:00:00 2001 From: Mavdol Date: Tue, 21 Apr 2026 01:07:46 +0200 Subject: [PATCH 09/10] docs: consolidate installation instructions into a single npm command in README --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 61ef0b2..7628dc1 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,8 @@ ## Getting Started ```bash -# Install the core bash package -npm install @capsule-run/bash - -# Install the default Wasm runtime -npm install @capsule-run/bash-wasm +# Install the core bash package & default Wasm runtime +npm install @capsule-run/bash @capsule-run/bash-wasm ``` ### TypeScript SDK From 84742e8c5382c95e2446721871b604b7585f5399 Mon Sep 17 00:00:00 2001 From: Mavdol Date: Tue, 21 Apr 2026 01:12:39 +0200 Subject: [PATCH 10/10] docs: update installation instructions and add usage example to README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7628dc1..27fc709 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,13 @@ ## Getting Started +### TypeScript SDK + ```bash -# Install the core bash package & default Wasm runtime npm install @capsule-run/bash @capsule-run/bash-wasm ``` -### TypeScript SDK +Run it: ```typescript import { Bash } from "@capsule-run/bash";