Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nullclaw/nullclaw/llms.txt

Use this file to discover all available pages before exploring further.

Shell Tool

The shell tool executes shell commands in the workspace directory with comprehensive security controls:
  • Command validation against SecurityPolicy
  • Environment sanitization to prevent API key leaks
  • Working directory control with cwd parameter
  • Timeout enforcement (default: 60 seconds)
  • Output limits (default: 1 MB)

Parameters

command
string
required
The shell command to execute
cwd
string
Working directory (absolute path within allowed paths; defaults to workspace)

Configuration

const st = try allocator.create(shell.ShellTool);
st.* = .{
    .workspace_dir = "/path/to/workspace",
    .allowed_paths = &.{},  // Additional allowed directories
    .timeout_ns = 60 * std.time.ns_per_s,  // 60 second default
    .max_output_bytes = 1_048_576,  // 1 MB default
    .policy = &security_policy,  // Optional SecurityPolicy
};

Usage

Basic Command

{
  "tool": "shell",
  "command": "ls -la"
}
Response:
total 24
drwxr-xr-x  5 user  staff  160 Mar  1 12:00 .
drwxr-xr-x  3 user  staff   96 Mar  1 11:00 ..
-rw-r--r--  1 user  staff  100 Mar  1 12:00 README.md
drwxr-xr-x  3 user  staff   96 Mar  1 11:30 src

Custom Working Directory

{
  "tool": "shell",
  "command": "pwd",
  "cwd": "/workspace/src"
}
Response:
/workspace/src

Pipeline Commands

{
  "tool": "shell",
  "command": "git status --short | grep M"
}
Response:
 M src/main.zig
 M src/config.zig

Security Model

SecurityPolicy Validation

When a SecurityPolicy is configured, all commands are validated before execution:
const policy = SecurityPolicy{
    .autonomy = .supervised,
    .workspace_dir = "/workspace",
    .allowed_commands = &.{ "git", "ls", "cat", "grep", "echo", "touch" },
    .require_approval_for_medium_risk = true,
    .block_high_risk_commands = true,
    .tracker = &rate_tracker,
};
Command Risk Levels:
  • Low risk — Read-only operations (ls, cat, grep, pwd, echo)
  • Medium risk — Write operations (touch, mkdir, git add, git commit)
  • High risk — Destructive operations (rm -rf, dd, mkfs, iptables, kill)
Policy Actions:
Risk Levelautonomy=supervisedautonomy=full
LowExecuteExecute
MediumRequire approval*Execute
HighBlock**Require approval
*If require_approval_for_medium_risk = true
**If block_high_risk_commands = true

Example: Approval Required

{
  "tool": "shell",
  "command": "touch test.txt"
}
Response (if approval required):
Command requires approval (medium/high risk): touch test.txt

Example: Blocked Command

{
  "tool": "shell",
  "command": "rm -rf /"
}
Response:
High-risk command blocked by security policy

Allowed Commands Allowlist

When allowed_commands is configured, only listed commands are permitted:
.allowed_commands = &.{ "git", "ls", "cat", "grep" },
{
  "tool": "shell",
  "command": "rm file.txt"
}
Response:
Command not allowed by security policy

Environment Sanitization

The shell tool clears all environment variables by default, then re-adds only safe functional variables: Safe environment variables:
  • PATH — Command search path
  • HOME — User home directory
  • TERM — Terminal type
  • LANG, LC_ALL, LC_CTYPE — Locale settings
  • USER — Username
  • SHELL — Default shell
  • TMPDIR — Temporary directory
Blocked variables:
  • OPENAI_API_KEY
  • ANTHROPIC_API_KEY
  • GEMINI_API_KEY
  • All other environment variables
This prevents accidental API key leaks via command injection (CWE-200).

Working Directory Control

Default: workspace_dir

By default, commands run in workspace_dir:
{
  "tool": "shell",
  "command": "pwd"
}
Response:
/workspace

Custom cwd (within workspace)

{
  "tool": "shell",
  "command": "ls",
  "cwd": "/workspace/src"
}
Response:
main.zig
config.zig
utils.zig

Custom cwd (outside workspace)

Requires allowed_paths configuration:
st.* = .{
    .workspace_dir = "/workspace",
    .allowed_paths = &.{
        "/data",
        "/home/user/projects",
    },
};
{
  "tool": "shell",
  "command": "ls",
  "cwd": "/data"
}
Allowed (in allowed_paths)
{
  "tool": "shell",
  "command": "ls",
  "cwd": "/etc"
}
Blocked:
cwd is outside allowed areas

cwd Validation Rules

  • cwd must be an absolute path
  • cwd must be within workspace_dir or allowed_paths
  • cwd is resolved with realpathAlloc() to prevent symlink escapes
  • Relative cwd is rejected: “cwd must be an absolute path”

Platform Shells

The shell tool uses the platform’s default shell:
PlatformShellCommand Format
macOS/bin/shsh -c "command"
Linux/bin/shsh -c "command"
Windowscmd.execmd.exe /c "command"
Commands are passed as a single string to the shell’s -c flag (Unix) or /c flag (Windows).

Timeout and Output Limits

Timeout

Commands are terminated after timeout_ns nanoseconds:
.timeout_ns = 60 * std.time.ns_per_s,  // 60 seconds
Example: Long-running command
{
  "tool": "shell",
  "command": "sleep 120"
}
Response (after 60 seconds):
Command terminated by signal

Output Limit

Stdout and stderr are truncated to max_output_bytes:
.max_output_bytes = 1_048_576,  // 1 MB
Example: Large output
{
  "tool": "shell",
  "command": "cat /dev/zero | head -c 10M"
}
Response:
[Binary output truncated to 1 MB]

Error Handling

Command Failure (Non-Zero Exit Code)

{
  "tool": "shell",
  "command": "ls /nonexistent"
}
Response:
ls: /nonexistent: No such file or directory
ToolResult.success = false

Signal Termination

{
  "tool": "shell",
  "command": "sleep 1000"
}
Response (after timeout):
Command terminated by signal

Missing Command

{
  "tool": "shell",
  "command": "nonexistent_program"
}
Response:
sh: nonexistent_program: command not found

No Output

If a command succeeds but produces no output:
{
  "tool": "shell",
  "command": "touch file.txt"
}
Response:
(no output)

Use Cases

Git Operations

{
  "tool": "shell",
  "command": "git status --short"
}

Build Commands

{
  "tool": "shell",
  "command": "zig build"
}
{
  "tool": "shell",
  "command": "find src -name '*.zig' | wc -l"
}

Testing

{
  "tool": "shell",
  "command": "zig build test --summary all"
}

System Info

{
  "tool": "shell",
  "command": "uname -a"
}
Always validate shell commands for security risks. Use SecurityPolicy to enforce safe command patterns.

Source

src/tools/shell.zig:21-117

Testing

Run shell tool tests:
zig build test --summary all
Tests cover:
  • Basic command execution
  • Path validation (cwd)
  • Policy enforcement
  • Timeout handling
  • Output limits
  • Error cases