TypeScript API reference#
Auto-generated reference for the @everruns/bashkit npm package. Reflects the latest published release.
Install with
npm install @everruns/bashkit. See the Embedding guide and LLM tools guide for task-oriented walkthroughs.
Bash#
Core bash interpreter with virtual filesystem.
State persists between calls — files created in one execute() are
available in subsequent calls.
import { Bash } from '@everruns/bashkit';
const bash = new Bash();
const result = bash.executeSync('echo "Hello, World!"');
console.log(result.stdout); // Hello, World!\n
Constructor#
new Bash(options?: BashOptions): Bash
addBuiltin#
bash.addBuiltin(name: string, callback: BuiltinCallback): void
Register a JS callback as a custom bash builtin.
The callback receives a BuiltinContext and returns the stdout to
emit. Sync (string) and async (Promise<string>) returns are both
supported. Exceptions become stderr + exit code 1.
Safe to call at any time — the new builtin is visible to the next
execute*() invocation with no interpreter rebuild or VFS disturbance.
Survives reset().
appendFile#
bash.appendFile(path: string, content: string): void
Append content to a file.
cancel#
bash.cancel(): void
Cancel the currently running execution.
chmod#
bash.chmod(path: string, mode: number): void
Change file permissions (octal mode, e.g. 0o755).
clearCancel#
bash.clearCancel(): void
Clear the cancellation flag so subsequent executions proceed normally.
Call this after cancel() once the in-flight execution has finished and
you want to reuse the same instance without discarding shell or VFS state.
execute#
bash.execute(commands: string, options?: ExecuteOptions): Promise<ExecResult>
Execute bash commands asynchronously, returning a Promise.
Non-blocking for the Node.js event loop.
If onOutput is provided, it receives chunk objects with { stdout, stderr }
during execution. Chunks are not line-aligned. The callback must be
synchronous; Promise-returning handlers are rejected. Do not re-enter the
same instance from onOutput via execute*, readFile, fs(), etc.
const result = await bash.execute('echo hello');
console.log(result.stdout); // hello\n
executeOrThrow#
bash.executeOrThrow(commands: string, options?: ExecuteOptions): Promise<ExecResult>
Execute bash commands asynchronously. Throws BashError on non-zero exit.
executeSync#
bash.executeSync(commands: string, options?: ExecuteOptions): ExecResult
Execute bash commands synchronously and return the result.
If signal is provided, the execution will be cancelled when the signal
is aborted. If onOutput is provided, it receives chunk objects with
{ stdout, stderr } during execution. Chunks are not line-aligned. The callback must be
synchronous; Promise-returning handlers are rejected. Do not re-enter the
same instance from onOutput via execute*, readFile, fs(), etc.
executeSyncOrThrow#
bash.executeSyncOrThrow(commands: string, options?: ExecuteOptions): ExecResult
Execute bash commands synchronously. Throws BashError on non-zero exit.
exists#
bash.exists(path: string): boolean
Check if a path exists in the virtual filesystem.
fs#
bash.fs(): FileSystem
Get a FileSystem handle for direct VFS operations.
glob#
bash.glob(pattern: string): string[]
Find files matching a name pattern. Returns absolute paths.
ls#
bash.ls(path?: string): string[]
List entry names in a directory. Returns empty array if directory does not exist.
mkdir#
bash.mkdir(path: string, recursive?: boolean): void
Create a directory. If recursive is true, creates parents as needed.
mount#
bash.mount(vfsPath: string, fs: FileSystem): void
Mount either a host directory or a FileSystem into the VFS.
readDir#
bash.readDir(path: string): ({ metadata: { created: number; fileType: string; mode: number; modified: number; size: number }; name: string })[]
List directory entries with metadata.
readFile#
bash.readFile(path: string): string
Read a file from the virtual filesystem as a UTF-8 string.
readLink#
bash.readLink(path: string): string
Read the target of a symbolic link.
remove#
bash.remove(path: string, recursive?: boolean): void
Remove a file or directory. If recursive is true, removes contents.
removeBuiltin#
bash.removeBuiltin(name: string): void
Remove a previously registered custom builtin.
reset#
bash.reset(): void
Reset interpreter to fresh state, preserving configuration.
restoreSnapshot#
bash.restoreSnapshot(data: Uint8Array, options?: SnapshotOptions): void
Restore interpreter state from a previously captured snapshot. Preserves current configuration (limits, builtins) but replaces shell state and VFS contents.
restoreSnapshotKeyed#
bash.restoreSnapshotKeyed(data: Uint8Array, key: Uint8Array): void
Restore interpreter state from a HMAC-protected snapshot.
shellState#
bash.shellState(): ShellState
Capture a lightweight snapshot of shell state (variables, env, cwd,
arrays, aliases, traps) for inspection — e.g. prompt rendering or
debugging. Function definitions are omitted; use snapshot() for full
state capture/restore.
snapshot#
bash.snapshot(options?: SnapshotOptions): Uint8Array
Serialize interpreter state (variables, VFS, counters) to a Uint8Array.
Use hmacKey when snapshots are stored outside the current trust boundary
(network, user uploads, shared storage). Without hmacKey, the snapshot
digest only detects accidental corruption and is forgeable.
const bash = new Bash();
await bash.execute("x=42");
const snapshot = bash.snapshot();
// persist snapshot...
const bash2 = Bash.fromSnapshot(snapshot);
const r = await bash2.execute("echo $x"); // "42\n"
snapshotKeyed#
bash.snapshotKeyed(key: Uint8Array, options?: SnapshotOptions): Uint8Array
Serialize interpreter state with HMAC-SHA256 using a caller-provided key. Use for snapshots crossing trust boundaries.
stat#
bash.stat(path: string): { created: number; fileType: string; mode: number; modified: number; size: number }
Get metadata for a path (fileType, size, mode, timestamps).
symlink#
bash.symlink(target: string, link: string): void
Create a symbolic link pointing to target.
unmount#
bash.unmount(vfsPath: string): void
Unmount a previously mounted filesystem.
writeFile#
bash.writeFile(path: string, content: string): void
Write a string to a file in the virtual filesystem.
create#
Bash.create(options?: BashOptions): Promise<Bash>
Create a Bash instance with support for async file providers.
Use this instead of new Bash() when file values are async functions.
const bash = await Bash.create({
files: {
"/data/remote.json": async () => await fetchData(),
}
});
fromSnapshot#
Bash.fromSnapshot(data: Uint8Array, options?: SnapshotOptions): Bash
Create a new Bash instance from a snapshot.
const snapshot = existingBash.snapshot();
const restored = Bash.fromSnapshot(snapshot);
fromSnapshotKeyed#
Bash.fromSnapshotKeyed(data: Uint8Array, key: Uint8Array): Bash
Create a new Bash instance from a HMAC-protected snapshot.
BashTool#
Bash interpreter with tool-contract metadata.
Use this when integrating with AI frameworks that need tool definitions.
import { BashTool } from '@everruns/bashkit';
const tool = new BashTool();
console.log(tool.name); // "bashkit"
console.log(tool.inputSchema()); // JSON schema string
console.log(tool.help()); // Markdown help document
const result = tool.executeSync('echo hello');
console.log(result.stdout); // hello\n
Constructor#
new BashTool(options?: BashOptions): BashTool
name#
name: string
Tool name.
shortDescription#
shortDescription: string
Short description.
version#
version: string
Tool version.
addBuiltin#
bashTool.addBuiltin(name: string, callback: BuiltinCallback): void
Register a JS callback as a custom builtin. See Bash.addBuiltin.
appendFile#
bashTool.appendFile(path: string, content: string): void
Append content to a file.
cancel#
bashTool.cancel(): void
Cancel the currently running execution.
chmod#
bashTool.chmod(path: string, mode: number): void
Change file permissions (octal mode, e.g. 0o755).
clearCancel#
bashTool.clearCancel(): void
Clear the cancellation flag so subsequent executions proceed normally.
Call this after cancel() once the in-flight execution has finished and
you want to reuse the same instance without discarding shell or VFS state.
description#
bashTool.description(): string
Token-efficient tool description.
execute#
bashTool.execute(commands: string, options?: ExecuteOptions): Promise<ExecResult>
Execute bash commands asynchronously, returning a Promise.
If onOutput is provided, it must be synchronous; Promise-returning
handlers are rejected. Do not re-enter the same instance from onOutput
via execute*, readFile, fs(), etc.
executeOrThrow#
bashTool.executeOrThrow(commands: string, options?: ExecuteOptions): Promise<ExecResult>
Execute bash commands asynchronously. Throws BashError on non-zero exit.
executeSync#
bashTool.executeSync(commands: string, options?: ExecuteOptions): ExecResult
Execute bash commands synchronously and return the result.
If onOutput is provided, it must be synchronous; Promise-returning
handlers are rejected. Do not re-enter the same instance from onOutput
via execute*, readFile, fs(), etc.
executeSyncOrThrow#
bashTool.executeSyncOrThrow(commands: string, options?: ExecuteOptions): ExecResult
Execute bash commands synchronously. Throws BashError on non-zero exit.
exists#
bashTool.exists(path: string): boolean
Check whether a path exists in the virtual filesystem.
fs#
bashTool.fs(): FileSystem
Get a FileSystem handle for direct VFS operations.
glob#
bashTool.glob(pattern: string): string[]
Find files matching a name pattern. Returns absolute paths.
help#
bashTool.help(): string
Markdown help document.
inputSchema#
bashTool.inputSchema(): string
JSON input schema as string.
ls#
bashTool.ls(path?: string): string[]
List entry names in a directory. Returns empty array if directory does not exist.
mkdir#
bashTool.mkdir(path: string, recursive?: boolean): void
Create a directory. If recursive is true, creates parents as needed.
mount#
bashTool.mount(vfsPath: string, fs: FileSystem): void
Mount either a host directory or a FileSystem into the VFS.
outputSchema#
bashTool.outputSchema(): string
JSON output schema as string.
readDir#
bashTool.readDir(path: string): ({ metadata: { created: number; fileType: string; mode: number; modified: number; size: number }; name: string })[]
List directory entries with metadata.
readFile#
bashTool.readFile(path: string): string
Read file contents from the virtual filesystem.
Throws BashError if the file does not exist.
readLink#
bashTool.readLink(path: string): string
Read the target of a symbolic link.
remove#
bashTool.remove(path: string, recursive?: boolean): void
Remove a file or directory. If recursive is true, removes contents.
removeBuiltin#
bashTool.removeBuiltin(name: string): void
Remove a previously registered custom builtin.
reset#
bashTool.reset(): void
Reset interpreter to fresh state, preserving configuration.
restoreSnapshot#
bashTool.restoreSnapshot(data: Uint8Array, options: SnapshotOptions & { hmacKey: Uint8Array }): void
Restore interpreter state from an HMAC-authenticated snapshot. Preserves current configuration (limits, identity) but replaces shell state and VFS contents.
restoreSnapshotKeyed#
bashTool.restoreSnapshotKeyed(data: Uint8Array, key: Uint8Array): void
Restore interpreter state from a HMAC-protected snapshot.
shellState#
bashTool.shellState(): ShellState
Capture a lightweight snapshot of shell state (variables, env, cwd,
arrays, aliases, traps) for inspection — e.g. prompt rendering or
debugging. Function definitions are omitted; use snapshot() for full
state capture/restore.
snapshot#
bashTool.snapshot(options: SnapshotOptions & { hmacKey: Uint8Array }): Uint8Array
Serialize interpreter state (variables, VFS, counters) to an
HMAC-authenticated Uint8Array. BashTool snapshots require hmacKey because
they include tenant-controlled shell state, VFS contents, and counters.
snapshotKeyed#
bashTool.snapshotKeyed(key: Uint8Array, options?: SnapshotOptions): Uint8Array
Serialize interpreter state with HMAC-SHA256 using a caller-provided key.
stat#
bashTool.stat(path: string): { created: number; fileType: string; mode: number; modified: number; size: number }
Get metadata for a path (fileType, size, mode, timestamps).
symlink#
bashTool.symlink(target: string, link: string): void
Create a symbolic link pointing to target.
systemPrompt#
bashTool.systemPrompt(): string
Compact system prompt for orchestration.
unmount#
bashTool.unmount(vfsPath: string): void
Unmount a previously mounted filesystem.
writeFile#
bashTool.writeFile(path: string, content: string): void
Write content to a file in the virtual filesystem. Creates parent directories as needed.
create#
BashTool.create(options?: BashOptions): Promise<BashTool>
Create a BashTool instance with support for async file providers.
fromSnapshot#
BashTool.fromSnapshot(data: Uint8Array, options: undefined | BashOptions, snapshotOptions: SnapshotOptions & { hmacKey: Uint8Array }): BashTool
Create a new BashTool instance from an HMAC-authenticated snapshot.
Any provided Bash options are applied before restoring the snapshot so limits and identity settings survive round-trips.
fromSnapshotKeyed#
BashTool.fromSnapshotKeyed(data: Uint8Array, key: Uint8Array, options?: BashOptions): BashTool
Create a new BashTool instance from a HMAC-protected snapshot.
ScriptedTool#
Compose JS callbacks as bash builtins for multi-tool orchestration.
Each registered tool becomes a bash builtin command. An LLM (or user) writes a single bash script that pipes, loops, and branches across all tools.
import { ScriptedTool } from '@everruns/bashkit';
const tool = new ScriptedTool({ name: "api" });
tool.addTool("greet", "Greet user",
(params) => `hello ${params.name ?? "world"}\n`
);
const result = tool.executeSync("greet --name Alice");
console.log(result.stdout); // hello Alice\n
Constructor#
new ScriptedTool(options: ScriptedToolOptions): ScriptedTool
name#
name: string
Tool name.
shortDescription#
shortDescription: string
Short description.
version#
version: string
Tool version.
addTool#
scriptedTool.addTool(name: string, description: string, callback: ToolCallback, schema?: Record<string, unknown>): void
Register a tool command.
description#
scriptedTool.description(): string
Token-efficient tool description.
env#
scriptedTool.env(key: string, value: string): void
Add an environment variable visible inside scripts.
execute#
scriptedTool.execute(commands: string): Promise<ExecResult>
Execute a bash script asynchronously, returning a Promise.
This is the recommended execution method for ScriptedTool since tool callbacks require the Node.js event loop to be running.
executeOrThrow#
scriptedTool.executeOrThrow(commands: string): Promise<ExecResult>
Execute asynchronously. Throws BashError on non-zero exit.
executeSync#
scriptedTool.executeSync(commands: string): ExecResult
Execute a bash script synchronously.
Note: ScriptedTool callbacks run asynchronously via Node’s event loop.
If a registered tool is invoked, this method returns a non-zero result
instead of queueing a callback that would deadlock. Use execute()
(async) for scripts that call registered tools. Only use this for scripts
that don’t invoke any registered tools (e.g., pure bash).
executeSyncOrThrow#
scriptedTool.executeSyncOrThrow(commands: string): ExecResult
Execute synchronously. Throws BashError on non-zero exit.
Same caveats as executeSync() — throws when a registered tool would
require the blocked Node event loop. Use executeOrThrow() instead.
help#
scriptedTool.help(): string
Markdown help document.
inputSchema#
scriptedTool.inputSchema(): string
JSON input schema as string.
outputSchema#
scriptedTool.outputSchema(): string
JSON output schema as string.
systemPrompt#
scriptedTool.systemPrompt(): string
Compact system prompt for orchestration.
toolCount#
scriptedTool.toolCount(): number
Number of registered tools.
FileSystem#
Constructor#
new FileSystem(): FileSystem
appendFile#
fileSystem.appendFile(path: string, content: string): void
chmod#
fileSystem.chmod(path: string, mode: number): void
copy#
fileSystem.copy(fromPath: string, toPath: string): void
exists#
fileSystem.exists(path: string): boolean
mkdir#
fileSystem.mkdir(path: string, recursive?: boolean): void
readDir#
fileSystem.readDir(path: string): ({ metadata: { created: number; fileType: string; mode: number; modified: number; size: number }; name: string })[]
readFile#
fileSystem.readFile(path: string): string
readLink#
fileSystem.readLink(path: string): string
remove#
fileSystem.remove(path: string, recursive?: boolean): void
rename#
fileSystem.rename(fromPath: string, toPath: string): void
stat#
fileSystem.stat(path: string): { created: number; fileType: string; mode: number; modified: number; size: number }
symlink#
fileSystem.symlink(target: string, link: string): void
toExternal#
fileSystem.toExternal(): unknown
writeFile#
fileSystem.writeFile(path: string, content: string): void
fromExternal#
FileSystem.fromExternal(external: unknown): FileSystem
fromNative#
FileSystem.fromNative(nativeFs: any): FileSystem
real#
FileSystem.real(hostPath: string, options: FileSystemRealOptions): FileSystem
BashError#
Error thrown when a bash command execution fails.
Properties#
exitCode—numberstderr—string
Constructor#
new BashError(result: ExecResult): BashError
display#
bashError.display(): string
getVersion()#
getVersion(): string
Get the bashkit version string.
BashOptions#
Options for creating a Bash or BashTool instance.
Fields#
-
allowedMountPaths?—string[]Allowlist of host path prefixes permitted for real filesystem mounts.
Required for
mountsand runtimemount()APIs. Mount targets must resolve under one of these prefixes; otherwise the call is rejected. -
customBuiltins?—Record<string, BuiltinCallback>Custom JS callbacks registered as bash builtins.
Each entry becomes a bash command that shares the instance’s VFS — files created by the callback persist across
execute()calls. Callbacks can be sync (stringreturn) or async (Promise<string>); exceptions surface as stderr with exit code 1.Equivalent to calling
addBuiltin(name, cb)for each entry. Survivesreset(); not preserved throughsnapshot()/restoreSnapshot()— pass the option again after restoring.Override precedence: shell function > POSIX special builtin > custom builtin > baked-in builtin > PATH.
-
cwd?—stringInitial working directory for the shell.
Sets the starting
cwddirectly instead of running a leadingcd "${cwd}"command, avoiding the parse/exec overhead. -
env?—Record<string, string>Initial environment variables, applied before execution.
Scripts see these immediately without an
exportprelude. Keys are variable names, values are their string values. -
externalFunctions?—string[]Names of external functions callable from embedded Python code.
These function names become available as Python builtins within the embedded interpreter. When called, they invoke the external handler.
-
files?—Record<string, FileValue>Files to mount in the virtual filesystem. Keys are absolute paths, values are content strings or lazy providers.
String values are mounted immediately. Function values are called on first read and the result is cached.
-
hostname?—string -
maxCommands?—number -
maxInputBytes?—numberMaximum script input size in UTF-8 bytes.
Async execute validates this before entering the per-instance queue so oversized calls cannot wait while retaining large command strings.
-
maxLoopIterations?—number -
maxMemory?—numberMaximum interpreter memory in bytes (variables, arrays, functions).
Caps the total byte budget for variable storage and function bodies. Prevents OOM from untrusted input such as exponential string doubling.
-
maxTotalLoopIterations?—number -
mounts?—({ path: string; root: string; writable?: boolean })[]Real filesystem mounts. Each mount maps a host directory into the VFS.
-
network?—NetworkOptionsOutbound network configuration. When set, enables
curl/wgetrestricted to the configured allowlist, with optional transparent credential injection. Omitted = network disabled (nocurl/wget).Must specify either
allow(list of URL patterns) orallowAll: true, not both.blockPrivateIpsdefaults totrue. -
python?—booleanEnable embedded Python execution (
python/python3builtins).When true, bash scripts can use
python -c '...'orpython3 script.pyto run Python code within the sandbox. -
sqlite?—booleanEnable the embedded SQLite builtin (
sqlite/sqlite3).Backed by Turso. When
true, the binding both registers the builtin and injectsBASHKIT_ALLOW_INPROCESS_SQLITE=1so the runtime gate is satisfied. Defaults tofalse. DefaultSqliteLimitsapply: 4 MiB script cap, 256 MiB DB cap, 30 s wall-clock budget, resource-affecting PRAGMAs andATTACH/DETACHrejected. -
timeoutMs?—numberExecution timeout in milliseconds.
When set, commands that exceed this duration are aborted with exit code 124 (matching the bash
timeoutconvention). -
username?—string
BuiltinContext#
Execution context passed to a custom builtin registered via
customBuiltins or addBuiltin.
name, argv, stdin, env, and cwd are snapshots of the shell
state at invocation time; fs is a live handle to the interpreter’s
virtual filesystem.
Fields#
-
argv—string[]Arguments (not including the command name).
-
cwd—stringCurrent working directory.
-
env—Record<string, string>Environment variables visible at the call site.
-
fs—FileSystemLive handle to the interpreter’s virtual filesystem — the same VFS the executing script sees. Reads observe earlier script writes and writes are visible to subsequent commands. Inherits mounts and read-only configuration.
-
name—stringThe command name as invoked.
-
stdin—null | stringPiped input, or
nullif there is no pipe.
CredentialHeader#
A single HTTP header (name/value pair) for credential injection.
Fields#
name—stringvalue—string
ExecResult#
Result from executing bash commands.
Fields#
-
error?—string -
exitCode—number -
finalEnv?—Record<string, string> -
stderr—string -
stderrTruncated—boolean -
stdout—string -
stdoutTruncated—boolean -
success—booleanTrue if exit_code is 0.
ExecuteOptions#
Fields#
-
onOutput?—OnOutputLive chunk callback. Must be synchronous.
Limitation: do not call back into the same
Bash/BashToolinstance from this handler (execute*,readFile,fs(), etc.). The current binding rejects same-instance re-entry to avoid deadlocks and runtime panics. -
signal?—AbortSignal
FileSystemRealOptions#
Standalone filesystem handle for direct VFS operations and native addon interop.
Fields#
allowedMountPaths—string[]writable?—boolean
NetworkCredential#
Credential injected into outbound HTTP requests matching pattern.
kind selects the shape: "bearer" (requires token), "header"
(requires name + value), or "headers" (requires headers).
Scripts never see the secret — it is attached on the wire only.
Fields#
-
headers?—CredentialHeader[]Header list (for
kind: "headers"). -
kind—stringOne of
"bearer","header","headers". -
name?—stringHeader name (for
kind: "header"). -
pattern—stringURL pattern the credential applies to (e.g.
https://api.example.com/**). -
token?—stringBearer token (for
kind: "bearer"). -
value?—stringHeader value (for
kind: "header").
NetworkCredentialPlaceholder#
Placeholder-mode credential injection: env is set to an opaque
placeholder value visible to scripts; outbound requests matching
pattern have the placeholder replaced with the real credential.
Fields#
-
env—stringEnvironment variable that receives the placeholder value.
-
headers?—CredentialHeader[]Header list (for
kind: "headers"). -
kind—stringOne of
"bearer","header","headers". -
name?—stringHeader name (for
kind: "header"). -
pattern—stringURL pattern the credential applies to.
-
token?—stringBearer token (for
kind: "bearer"). -
value?—stringHeader value (for
kind: "header").
NetworkOptions#
Outbound network configuration (enables curl/wget).
Must specify either allow (list of URL patterns) or allowAll: true,
not both. blockPrivateIps defaults to true.
Fields#
-
allow?—string[]URL patterns permitted for outbound requests.
-
allowAll?—booleanAllow all outbound requests (mutually exclusive with
allow). -
blockPrivateIps?—booleanBlock requests resolving to private/loopback IPs (default: true).
-
credentialPlaceholders?—NetworkCredentialPlaceholder[]Placeholder-mode credential injection (see type docs).
-
credentials?—NetworkCredential[]Credentials injected transparently into matching requests.
OutputChunk#
Fields#
stderr—stringstdout—string
ScriptedToolOptions#
Options for creating a ScriptedTool instance.
Fields#
maxCommands?—numbermaxLoopIterations?—numbername—stringshortDescription?—string
ShellState#
Lightweight snapshot of shell state for inspection (prompt rendering,
debugging). Mirrors the Python binding’s ShellState; omits function
definitions (use snapshot() for full state capture/restore).
Fields#
-
aliases—Record<string, string>Shell aliases.
-
arrays—Record<string, Record<string, string>>Indexed arrays: name → { index (as string) → value }. Sparse indices are preserved, hence a map rather than a dense JS array.
-
assocArrays—Record<string, Record<string, string>>Associative arrays: name → { key → value }.
-
cwd—stringCurrent working directory.
-
env—Record<string, string>Environment variables.
-
lastExitCode—numberExit code of the last executed command.
-
traps—Record<string, string>Trap handlers keyed by signal/condition name.
-
variables—Record<string, string>Shell variables (non-exported).
SnapshotOptions#
Fields#
-
excludeFilesystem?—boolean -
excludeFunctions?—boolean -
hmacKey?—Uint8Array<ArrayBufferLike>Secret key used to authenticate snapshot bytes with HMAC-SHA256. Required for BashTool snapshots because tool snapshots may cross tenant or network trust boundaries. Recommended for any snapshot accepted from users, shared storage, or remote callers.
BuiltinCallback#
Callback signature for custom builtins. Return the stdout to emit.
Both sync (string) and async (Promise<string>) returns are supported.
Exceptions / rejections surface as stderr with exit code 1.
type BuiltinCallback = (ctx: BuiltinContext) => string | Promise<string>
FileValue#
A file value: either a string, a sync function returning a string,
or an async function returning a Promise
Function values are resolved lazily on first read and cached.
type FileValue = string | () => string | () => Promise<string>
OnOutput#
type OnOutput = (chunk: OutputChunk) => void
ToolCallback#
Callback type for ScriptedTool tool commands.
Receives parsed --key value flags as params and optional piped input as stdin.
Must return a string.
type ToolCallback = (params: Record<string, unknown>, stdin: string | null) => string
Framework integrations#
@everruns/bashkit/langchain#
LangChain.js integration for Bashkit.
Provides LangChain-compatible tools wrapping BashTool and ScriptedTool for use with LangChain agents and chains.
import { createBashTool, createScriptedTool } from '@everruns/bashkit/langchain';
// Basic bash tool
const tool = createBashTool();
const result = await tool.invoke({ commands: "echo hello" });
// Scripted tool
import { ScriptedTool } from '@everruns/bashkit';
const st = new ScriptedTool({ name: "api" });
st.addTool("greet", "Greet user", (p) => `hello ${p.name}\n`);
const langchainTool = createScriptedTool(st);
createBashTool()#
createBashTool(options?: Omit<BashOptions, "files">): DynamicStructuredTool
Create a LangChain-compatible Bashkit tool.
Returns a DynamicStructuredTool that can be passed directly to
LangChain agents like createReactAgent.
import { createBashTool } from '@everruns/bashkit/langchain';
import { createReactAgent } from '@langchain/langgraph/prebuilt';
const tool = createBashTool({ username: "agent" });
const agent = createReactAgent({ llm: model, tools: [tool] });
createScriptedTool()#
createScriptedTool(scriptedTool: ScriptedTool): DynamicStructuredTool
Create a LangChain-compatible tool from a configured ScriptedTool.
The ScriptedTool should already have tools registered via addTool().
import { ScriptedTool } from '@everruns/bashkit';
import { createScriptedTool } from '@everruns/bashkit/langchain';
const st = new ScriptedTool({ name: "api" });
st.addTool("get_data", "Fetch data", (p) => JSON.stringify({ id: p.id }));
const tool = createScriptedTool(st);
@everruns/bashkit/anthropic#
Anthropic SDK adapter for Bashkit.
Returns a ready-to-use { system, tools, handler } object for Claude’s
messages.create() API, eliminating boilerplate for tool integration.
import Anthropic from "@anthropic-ai/sdk";
import { bashTool } from "@everruns/bashkit/anthropic";
const client = new Anthropic();
const bash = bashTool();
const response = await client.messages.create({
model: "claude-haiku-4-5-20251001",
max_tokens: 1024,
system: bash.system,
tools: bash.tools,
messages: [{ role: "user", content: "List files in /home" }],
});
for (const block of response.content) {
if (block.type === "tool_use") {
const result = await bash.handler(block);
// send result back as tool_result
}
}
bashTool()#
bashTool(options?: BashToolOptions): BashToolAdapter
Create a bash tool adapter for the Anthropic SDK.
Returns { system, tools, handler } that plugs directly into
client.messages.create().
import Anthropic from "@anthropic-ai/sdk";
import { bashTool } from "@everruns/bashkit/anthropic";
const client = new Anthropic();
const bash = bashTool({ files: { "/data.txt": "hello" } });
const response = await client.messages.create({
model: "claude-haiku-4-5-20251001",
max_tokens: 256,
system: bash.system,
tools: bash.tools,
messages: [{ role: "user", content: "Read /data.txt" }],
});
BashToolAdapter#
Return value of bashTool().
Fields#
-
bash—BashToolThe underlying BashTool instance for direct access.
-
handler—(toolUse: ToolUseBlock, options: HandlerOptions) => Promise<ToolResult>Handler that executes a tool_use block and returns a tool_result.
Pass an AbortSignal via the options parameter to cancel execution when the framework aborts the tool call:
const controller = new AbortController(); const result = await bash.handler(block, { signal: controller.signal }); -
system—stringSystem prompt describing bash capabilities and constraints.
-
tools—AnthropicTool[]Tool definitions for Anthropic’s messages.create() API.
BashToolOptions#
Options for configuring the bash tool adapter.
Fields#
-
allowedMountPaths?—string[]Allowlist of host path prefixes permitted for real filesystem mounts.
Required for
mountsand runtimemount()APIs. Mount targets must resolve under one of these prefixes; otherwise the call is rejected. -
customBuiltins?—Record<string, BuiltinCallback>Custom JS callbacks registered as bash builtins.
Each entry becomes a bash command that shares the instance’s VFS — files created by the callback persist across
execute()calls. Callbacks can be sync (stringreturn) or async (Promise<string>); exceptions surface as stderr with exit code 1.Equivalent to calling
addBuiltin(name, cb)for each entry. Survivesreset(); not preserved throughsnapshot()/restoreSnapshot()— pass the option again after restoring.Override precedence: shell function > POSIX special builtin > custom builtin > baked-in builtin > PATH.
-
cwd?—stringInitial working directory for the shell.
Sets the starting
cwddirectly instead of running a leadingcd "${cwd}"command, avoiding the parse/exec overhead. -
env?—Record<string, string>Initial environment variables, applied before execution.
Scripts see these immediately without an
exportprelude. Keys are variable names, values are their string values. -
externalFunctions?—string[]Names of external functions callable from embedded Python code.
These function names become available as Python builtins within the embedded interpreter. When called, they invoke the external handler.
-
files?—Record<string, string>Pre-populate VFS files. Keys are absolute paths, values are file contents.
-
hostname?—string -
maxCommands?—number -
maxInputBytes?—numberMaximum script input size in UTF-8 bytes.
Async execute validates this before entering the per-instance queue so oversized calls cannot wait while retaining large command strings.
-
maxLoopIterations?—number -
maxMemory?—numberMaximum interpreter memory in bytes (variables, arrays, functions).
Caps the total byte budget for variable storage and function bodies. Prevents OOM from untrusted input such as exponential string doubling.
-
maxOutputLength?—numberMaximum output length in characters (default: 100000).
Output exceeding this limit is truncated with a
[truncated]marker. Prevents context window flooding when scripts produce large output. -
maxTotalLoopIterations?—number -
mounts?—({ path: string; root: string; writable?: boolean })[]Real filesystem mounts. Each mount maps a host directory into the VFS.
-
network?—NetworkOptionsOutbound network configuration. When set, enables
curl/wgetrestricted to the configured allowlist, with optional transparent credential injection. Omitted = network disabled (nocurl/wget).Must specify either
allow(list of URL patterns) orallowAll: true, not both.blockPrivateIpsdefaults totrue. -
python?—booleanEnable embedded Python execution (
python/python3builtins).When true, bash scripts can use
python -c '...'orpython3 script.pyto run Python code within the sandbox. -
sanitizeOutput?—booleanWrap tool output in XML boundary markers (default: false).
When enabled, output is wrapped in
<tool_output>...</tool_output>tags to help LLMs distinguish tool output data from instructions, reducing prompt injection risk via tool output.Security note: This is a defense-in-depth measure. Tool output from untrusted sources (files, network) may contain text that attempts to manipulate LLM behavior. Boundary markers help but do not eliminate this risk.
-
sqlite?—booleanEnable the embedded SQLite builtin (
sqlite/sqlite3).Backed by Turso. When
true, the binding both registers the builtin and injectsBASHKIT_ALLOW_INPROCESS_SQLITE=1so the runtime gate is satisfied. Defaults tofalse. DefaultSqliteLimitsapply: 4 MiB script cap, 256 MiB DB cap, 30 s wall-clock budget, resource-affecting PRAGMAs andATTACH/DETACHrejected. -
timeoutMs?—numberExecution timeout in milliseconds.
When set, this is passed to the underlying BashTool as
timeoutMs. Commands exceeding this duration are aborted with exit code 124. Framework-level timeouts can be propagated here to ensure bashkit stops execution when the framework cancels a tool call. -
username?—string
HandlerOptions#
Options for handler invocation.
Fields#
-
signal?—AbortSignalAbortSignal to cancel execution when the framework aborts the tool call.
ToolResult#
Result from handling a tool call, ready to send back as tool_result.
Fields#
content—stringis_error?—booleantool_use_id—stringtype—"tool_result"
@everruns/bashkit/openai#
OpenAI SDK adapter for Bashkit.
Returns a ready-to-use { system, tools, handler } object for OpenAI’s
chat.completions.create() API.
import OpenAI from "openai";
import { bashTool } from "@everruns/bashkit/openai";
const client = new OpenAI();
const bash = bashTool();
const response = await client.chat.completions.create({
model: "gpt-4.1-mini",
tools: bash.tools,
messages: [
{ role: "system", content: bash.system },
{ role: "user", content: "Create a file with today's date" },
],
});
for (const call of response.choices[0].message.tool_calls ?? []) {
const result = await bash.handler(call);
// send result back as tool message
}
bashTool()#
bashTool(options?: BashToolOptions): BashToolAdapter
Create a bash tool adapter for the OpenAI SDK.
Returns { system, tools, handler } that plugs directly into
client.chat.completions.create().
import OpenAI from "openai";
import { bashTool } from "@everruns/bashkit/openai";
const client = new OpenAI();
const bash = bashTool({ files: { "/data.txt": "42" } });
const response = await client.chat.completions.create({
model: "gpt-4.1-nano",
tools: bash.tools,
messages: [
{ role: "system", content: bash.system },
{ role: "user", content: "What's in /data.txt?" },
],
});
BashToolAdapter#
Return value of bashTool().
Fields#
-
bash—BashToolThe underlying BashTool instance for direct access.
-
handler—(toolCall: OpenAIToolCall, options: HandlerOptions) => Promise<ToolResult>Handler that executes a tool_call and returns a tool message.
Pass an AbortSignal via the options parameter to cancel execution when the framework aborts the tool call:
const controller = new AbortController(); const result = await bash.handler(call, { signal: controller.signal }); -
system—stringSystem prompt describing bash capabilities and constraints.
-
tools—OpenAITool[]Tool definitions for OpenAI’s chat.completions.create() API.
BashToolOptions#
Options for configuring the bash tool adapter.
Fields#
-
allowedMountPaths?—string[]Allowlist of host path prefixes permitted for real filesystem mounts.
Required for
mountsand runtimemount()APIs. Mount targets must resolve under one of these prefixes; otherwise the call is rejected. -
customBuiltins?—Record<string, BuiltinCallback>Custom JS callbacks registered as bash builtins.
Each entry becomes a bash command that shares the instance’s VFS — files created by the callback persist across
execute()calls. Callbacks can be sync (stringreturn) or async (Promise<string>); exceptions surface as stderr with exit code 1.Equivalent to calling
addBuiltin(name, cb)for each entry. Survivesreset(); not preserved throughsnapshot()/restoreSnapshot()— pass the option again after restoring.Override precedence: shell function > POSIX special builtin > custom builtin > baked-in builtin > PATH.
-
cwd?—stringInitial working directory for the shell.
Sets the starting
cwddirectly instead of running a leadingcd "${cwd}"command, avoiding the parse/exec overhead. -
env?—Record<string, string>Initial environment variables, applied before execution.
Scripts see these immediately without an
exportprelude. Keys are variable names, values are their string values. -
externalFunctions?—string[]Names of external functions callable from embedded Python code.
These function names become available as Python builtins within the embedded interpreter. When called, they invoke the external handler.
-
files?—Record<string, string>Pre-populate VFS files. Keys are absolute paths, values are file contents.
-
hostname?—string -
maxCommands?—number -
maxInputBytes?—numberMaximum script input size in UTF-8 bytes.
Async execute validates this before entering the per-instance queue so oversized calls cannot wait while retaining large command strings.
-
maxLoopIterations?—number -
maxMemory?—numberMaximum interpreter memory in bytes (variables, arrays, functions).
Caps the total byte budget for variable storage and function bodies. Prevents OOM from untrusted input such as exponential string doubling.
-
maxOutputLength?—numberMaximum output length in characters (default: 100000).
Output exceeding this limit is truncated with a
[truncated]marker. Prevents context window flooding when scripts produce large output. -
maxTotalLoopIterations?—number -
mounts?—({ path: string; root: string; writable?: boolean })[]Real filesystem mounts. Each mount maps a host directory into the VFS.
-
network?—NetworkOptionsOutbound network configuration. When set, enables
curl/wgetrestricted to the configured allowlist, with optional transparent credential injection. Omitted = network disabled (nocurl/wget).Must specify either
allow(list of URL patterns) orallowAll: true, not both.blockPrivateIpsdefaults totrue. -
python?—booleanEnable embedded Python execution (
python/python3builtins).When true, bash scripts can use
python -c '...'orpython3 script.pyto run Python code within the sandbox. -
sanitizeOutput?—booleanWrap tool output in XML boundary markers (default: false).
When enabled, output is wrapped in
<tool_output>...</tool_output>tags to help LLMs distinguish tool output data from instructions, reducing prompt injection risk via tool output. -
sqlite?—booleanEnable the embedded SQLite builtin (
sqlite/sqlite3).Backed by Turso. When
true, the binding both registers the builtin and injectsBASHKIT_ALLOW_INPROCESS_SQLITE=1so the runtime gate is satisfied. Defaults tofalse. DefaultSqliteLimitsapply: 4 MiB script cap, 256 MiB DB cap, 30 s wall-clock budget, resource-affecting PRAGMAs andATTACH/DETACHrejected. -
timeoutMs?—numberExecution timeout in milliseconds.
When set, this is passed to the underlying BashTool as
timeoutMs. Commands exceeding this duration are aborted with exit code 124. Framework-level timeouts can be propagated here to ensure bashkit stops execution when the framework cancels a tool call. -
username?—string
HandlerOptions#
Options for handler invocation.
Fields#
-
signal?—AbortSignalAbortSignal to cancel execution when the framework aborts the tool call.
ToolResult#
Result from handling a tool call, ready to send as a tool message.
Fields#
content—stringrole—"tool"tool_call_id—string
@everruns/bashkit/ai#
Vercel AI SDK adapter for Bashkit.
Returns { system, tools } that plugs directly into generateText() /
streamText() with zero boilerplate. Tools include built-in execute
functions, so the AI SDK auto-executes tool calls in its maxSteps loop.
import { generateText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { bashTool } from "@everruns/bashkit/ai";
const bash = bashTool({
files: { "/home/user/data.csv": "name,age\nAlice,30\nBob,25" },
});
const { text } = await generateText({
model: anthropic("claude-haiku-4-5-20251001"),
system: bash.system,
tools: bash.tools,
maxSteps: 5,
prompt: "Analyze the CSV file and tell me the average age",
});
bashTool()#
bashTool(options?: BashToolOptions): BashToolAdapter
Create a bash tool adapter for the Vercel AI SDK.
Returns { system, tools } that plugs directly into generateText() or
streamText(). The tool includes a built-in execute function, so tool
calls are auto-executed when using maxSteps.
import { generateText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { bashTool } from "@everruns/bashkit/ai";
const bash = bashTool({ files: { "/test.txt": "hello world" } });
const { text } = await generateText({
model: anthropic("claude-haiku-4-5-20251001"),
system: bash.system,
tools: bash.tools,
maxSteps: 3,
prompt: "Read /test.txt and tell me what it says",
});
BashToolAdapter#
Return value of bashTool().
Fields#
-
bash—BashToolThe underlying BashTool instance for direct access.
-
system—stringSystem prompt describing bash capabilities and constraints.
-
tools—Record<string, AiTool>Tool definitions for Vercel AI SDK’s generateText/streamText.
BashToolOptions#
Options for configuring the bash tool adapter.
Fields#
-
allowedMountPaths?—string[]Allowlist of host path prefixes permitted for real filesystem mounts.
Required for
mountsand runtimemount()APIs. Mount targets must resolve under one of these prefixes; otherwise the call is rejected. -
customBuiltins?—Record<string, BuiltinCallback>Custom JS callbacks registered as bash builtins.
Each entry becomes a bash command that shares the instance’s VFS — files created by the callback persist across
execute()calls. Callbacks can be sync (stringreturn) or async (Promise<string>); exceptions surface as stderr with exit code 1.Equivalent to calling
addBuiltin(name, cb)for each entry. Survivesreset(); not preserved throughsnapshot()/restoreSnapshot()— pass the option again after restoring.Override precedence: shell function > POSIX special builtin > custom builtin > baked-in builtin > PATH.
-
cwd?—stringInitial working directory for the shell.
Sets the starting
cwddirectly instead of running a leadingcd "${cwd}"command, avoiding the parse/exec overhead. -
env?—Record<string, string>Initial environment variables, applied before execution.
Scripts see these immediately without an
exportprelude. Keys are variable names, values are their string values. -
externalFunctions?—string[]Names of external functions callable from embedded Python code.
These function names become available as Python builtins within the embedded interpreter. When called, they invoke the external handler.
-
files?—Record<string, string>Pre-populate VFS files. Keys are absolute paths, values are file contents.
-
hostname?—string -
maxCommands?—number -
maxInputBytes?—numberMaximum script input size in UTF-8 bytes.
Async execute validates this before entering the per-instance queue so oversized calls cannot wait while retaining large command strings.
-
maxLoopIterations?—number -
maxMemory?—numberMaximum interpreter memory in bytes (variables, arrays, functions).
Caps the total byte budget for variable storage and function bodies. Prevents OOM from untrusted input such as exponential string doubling.
-
maxTotalLoopIterations?—number -
mounts?—({ path: string; root: string; writable?: boolean })[]Real filesystem mounts. Each mount maps a host directory into the VFS.
-
network?—NetworkOptionsOutbound network configuration. When set, enables
curl/wgetrestricted to the configured allowlist, with optional transparent credential injection. Omitted = network disabled (nocurl/wget).Must specify either
allow(list of URL patterns) orallowAll: true, not both.blockPrivateIpsdefaults totrue. -
python?—booleanEnable embedded Python execution (
python/python3builtins).When true, bash scripts can use
python -c '...'orpython3 script.pyto run Python code within the sandbox. -
sqlite?—booleanEnable the embedded SQLite builtin (
sqlite/sqlite3).Backed by Turso. When
true, the binding both registers the builtin and injectsBASHKIT_ALLOW_INPROCESS_SQLITE=1so the runtime gate is satisfied. Defaults tofalse. DefaultSqliteLimitsapply: 4 MiB script cap, 256 MiB DB cap, 30 s wall-clock budget, resource-affecting PRAGMAs andATTACH/DETACHrejected. -
timeoutMs?—numberExecution timeout in milliseconds.
When set, commands that exceed this duration are aborted with exit code 124 (matching the bash
timeoutconvention). -
username?—string