bash-tool
Generic bash tool for AI agents, compatible with AI SDK.
Installation
npm install bash-tool just-bash
For full VM support, install @vercel/sandbox or another sandbox product instead of just-bash.
Usage
import { createBashTool } from "bash-tool";
import { ToolLoopAgent, stepCountIs } from "ai";
const { tools } = await createBashTool({
files: {
"src/index.ts": "export const hello = 'world';",
"package.json": '{"name": "my-project"}',
},
});
const agent = new ToolLoopAgent({
model: yourModel,
tools,
stopWhen: stepCountIs(20),
});
const result = await agent.generate({
prompt: "Analyze the project and create a summary report",
});
Tools
The tools object contains three tools that can be used by AI agents:
bash
Execute bash commands in the sandbox environment. For analysis agents, this may be the only tool you need to give to the agent.
Input:
command (string): The bash command to execute
Returns:
stdout (string): Standard output from the command
stderr (string): Standard error from the command
exitCode (number): Exit code of the command
readFile
Read the contents of a file from the sandbox.
Input:
path (string): The path to the file to read
Returns:
content (string): The file contents
writeFile
Write content to a file in the sandbox. Creates parent directories if needed.
Input:
path (string): The path where the file should be written
content (string): The content to write to the file
Returns:
success (boolean): true if the write succeeded
Advanced Usage
Upload a local directory
const { bash } = await createBashTool({
uploadDirectory: {
source: "./my-project",
include: "**/*.{ts,json}",
},
});
import { Sandbox } from "@vercel/sandbox";
const sandbox = await Sandbox.create();
const { tools } = await createBashTool({
sandbox,
files: { "index.ts": "console.log('hello');" },
});
Persistent sandbox across serverless invocations
Use Sandbox.get to reconnect to an existing sandbox by ID:
import { Sandbox } from "@vercel/sandbox";
const newSandbox = await Sandbox.create();
const sandboxId = newSandbox.sandboxId;
const existingSandbox = await Sandbox.get({ sandboxId });
const { tools } = await createBashTool({ sandbox: existingSandbox });
Use a custom just-bash instance
import { Bash } from "just-bash";
const sandbox = new Bash({ cwd: "/app" });
const { tools } = await createBashTool({
sandbox,
destination: "/app",
});
Intercept bash commands
const { tools } = await createBashTool({
onBeforeBashCall: ({ command }) => {
console.log("Running:", command);
if (command.includes("rm -rf")) {
return { command: "echo 'Blocked dangerous command'" };
}
},
onAfterBashCall: ({ command, result }) => {
console.log(`Exit code: ${result.exitCode}`);
return { result: { ...result, stdout: result.stdout.trim() } };
},
});
Custom sandbox implementation
import { createBashTool, Sandbox } from "bash-tool";
const customSandbox: Sandbox = {
async executeCommand(command) {
return { stdout: "", stderr: "", exitCode: 0 };
},
async readFile(path) {
return "";
},
async writeFiles(files) {
},
};
const { tools } = await createBashTool({ sandbox: customSandbox });
Skills (Experimental)
Skills are modular capabilities that extend agent functionality. Each skill is a directory containing a SKILL.md file with instructions and optional scripts.
import {
experimental_createSkillTool as createSkillTool,
createBashTool,
} from "bash-tool";
import { ToolLoopAgent } from "ai";
const { loadSkill, files, instructions } = await createSkillTool({
skillsDirectory: "./skills",
});
const { tools } = await createBashTool({
files,
extraInstructions: instructions,
});
const agent = new ToolLoopAgent({
model,
tools: { loadSkill, ...tools },
});
Skill Directory Structure
skills/
├── csv/
│ ├── SKILL.md # Required: instructions with YAML frontmatter
│ ├── analyze.sh # Optional: scripts the agent can run
│ └── filter.sh
└── text/
├── SKILL.md
└── search.sh
SKILL.md Format
---
name: csv
description: Analyze and transform CSV files
---
# CSV Processing
Use `./skills/csv/analyze.sh <file>` to analyze a CSV file.
How It Works
-
createSkillTool discovers skills and returns:
loadSkill - Tool for the agent to load a skill's instructions on demand
files - All skill files to pass to createBashTool
instructions - Extra instructions listing available skills
-
The agent sees skill names in the loadSkill tool description
-
When the agent needs a skill, it calls loadSkill("csv") to get detailed instructions
-
The agent uses bash to run scripts from ./skills/csv/
AI Agent Instructions
For AI agents working with bash-tool, additional guidance is available in AGENTS.md:
cat node_modules/bash-tool/dist/AGENTS.md
License
MIT