Back to Eliza

@elizaos/plugin-shell

plugins/plugin-shell/README.md

2.0.114.2 KB
Original Source

@elizaos/plugin-shell

A comprehensive shell command execution plugin for ElizaOS with PTY support, background execution, session management, and security restrictions.

Key Features:

  • ๐Ÿ”„ PTY Support - Run interactive terminal applications with full pseudo-terminal support
  • โฑ๏ธ Background Execution - Long-running commands automatically background with session management
  • ๐Ÿ“‹ Session Management - Track, poll, and interact with running processes
  • ๐Ÿ”’ Security First - Directory restrictions, forbidden commands, and timeout protection
  • ๐Ÿ“ Command History - Per-conversation command tracking

Available in three languages:

  • ๐ŸŸฆ TypeScript - Primary implementation for Node.js (full feature support)
  • ๐Ÿ Python - Native Python implementation
  • ๐Ÿฆ€ Rust - High-performance Rust implementation

๐Ÿšจ TL;DR - Quick Setup

Just want your agent to execute commands? Here's the fastest path:

  1. Install the plugin:

    bash
    cd your-eliza-project
    bun add @elizaos/plugin-shell
    
  2. Create/update your .env:

    bash
    SHELL_ALLOWED_DIRECTORY=/path/to/safe/directory
    
  3. Add to your character:

    typescript
    const character = {
      // ... other config
      plugins: ["@elizaos/plugin-shell"],
    };
    
  4. Run: bun start

โš ๏ธ Security note: The agent can ONLY execute commands within SHELL_ALLOWED_DIRECTORY - choose wisely!

Features

Core Features

  • โœ… Cross-platform support: Works on Linux, macOS, and Windows
  • โœ… Directory restriction: Commands are restricted to a specified directory for safety
  • โœ… Command filtering: Configurable list of forbidden commands
  • โœ… Timeout protection: Automatic termination of long-running commands
  • โœ… Command history: Tracks command execution history per conversation
  • โœ… File operation tracking: Monitors file creation, modification, and deletion
  • โœ… Shell context provider: Provides command history and working directory to agent context
  • โœ… Output capture: Returns both stdout and stderr from executed commands
  • โœ… Safety first: Disabled by default, requires explicit enabling

Advanced Features (TypeScript)

  • โœ… PTY Support: Run interactive terminal applications (vim, htop, etc.) with @lydell/node-pty
  • โœ… Background Execution: Commands automatically background after configurable yield window
  • โœ… Session Management: Track running/finished sessions, poll output, send keys
  • โœ… Process Control: List, poll, log, write, send-keys, submit, paste, kill, clear, remove
  • โœ… Output Truncation: Configurable max output with intelligent truncation
  • โœ… Platform-specific Shell: Auto-detects shell (bash, sh, PowerShell on Windows)

Project Structure

plugin-shell/
โ”œโ”€โ”€ typescript/          # TypeScript implementation
โ”‚   โ”œโ”€โ”€ providers/       # SHELL_HISTORY provider
โ”‚   โ”œโ”€โ”€ services/        # ShellService
โ”‚   โ”œโ”€โ”€ utils/           # Path validation, security checks
โ”‚   โ”œโ”€โ”€ types/           # Type definitions
โ”‚   โ””โ”€โ”€ __tests__/       # Unit tests
โ”œโ”€โ”€ python/              # Python implementation
โ”‚   โ”œโ”€โ”€ elizaos_plugin_shell/
โ”‚   โ”‚   โ”œโ”€โ”€ service.py   # ShellService
โ”‚   โ”‚   โ”œโ”€โ”€ path_utils.py
โ”‚   โ”‚   โ””โ”€โ”€ types.py
โ”‚   โ””โ”€โ”€ tests/           # Python tests
โ”œโ”€โ”€ rust/                # Rust implementation
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ lib.rs
โ”‚   โ”‚   โ”œโ”€โ”€ service.rs   # ShellService
โ”‚   โ”‚   โ”œโ”€โ”€ path_utils.rs
โ”‚   โ”‚   โ””โ”€โ”€ types.rs
โ”‚   โ””โ”€โ”€ tests/           # Integration tests
โ””โ”€โ”€ package.json         # NPM package config

Installation

TypeScript (Node.js)

bash
# Using bun (recommended)
bun add @elizaos/plugin-shell

# Using npm
npm install @elizaos/plugin-shell

Configuration

Set the following environment variables:

bash
# Set the allowed directory (commands can only run here)
SHELL_ALLOWED_DIRECTORY=/home/user/safe-workspace

# OPTIONAL: Set custom timeout in milliseconds (default: 30000)
SHELL_TIMEOUT=60000

# OPTIONAL: Add additional forbidden commands (comma-separated)
SHELL_FORBIDDEN_COMMANDS=rm,mv,cp,chmod,chown,shutdown,reboot

# OPTIONAL: Maximum output characters to capture (default: 200000)
SHELL_MAX_OUTPUT_CHARS=200000

# OPTIONAL: Milliseconds before backgrounding (default: 10000)
SHELL_BACKGROUND_MS=10000

# OPTIONAL: Allow background execution (default: true)
SHELL_ALLOW_BACKGROUND=true

# OPTIONAL: Session record TTL in milliseconds (default: 1800000 = 30min)
SHELL_JOB_TTL_MS=1800000

Usage Examples

TypeScript

typescript
import { shellPlugin, ShellService } from "@elizaos/plugin-shell";

// Use as a plugin
const character = {
  plugins: [shellPlugin],
};

// Or use the service directly
const service = new ShellService(runtime);
const result = await service.executeCommand("ls -la", "conversation-123");

// Advanced: Use exec with PTY and background support
const execResult = await service.exec("npm install", {
  pty: true,         // Run with pseudo-terminal
  background: false, // Or yieldMs: 5000 to auto-background after 5s
  timeout: 300,      // 5 minute timeout
  workdir: "/project",
});

if (execResult.status === "running") {
  console.log(`Background session: ${execResult.sessionId}`);
  
  // Poll for updates
  const pollResult = await service.processAction({
    action: "poll",
    sessionId: execResult.sessionId,
  });
  console.log(pollResult.message);
}

// Get the service from an Eliza agent runtime
const shellService = runtime.getService<ShellService>("shell");

๐Ÿ“‹ Shell Operations

Shell execution is exposed through the canonical SHELL action in @elizaos/plugin-coding-tools. This plugin supplies the shell service, approval service, and history provider.

Executes ANY shell command within the allowed directory, including file operations.

Examples:

  • run ls -la - List files with details
  • execute npm test - Run tests
  • create a file called hello.txt - Creates a new file
  • check git status - Show git repository status

MANAGE_PROCESS

Manage running and finished shell sessions. Supports the following operations:

ActionDescription
listList all running and finished sessions
pollGet new output from a running session
logGet session output with offset/limit
writeWrite data to session stdin
send-keysSend terminal key sequences (arrows, ctrl, etc)
submitSend carriage return (Enter)
pastePaste text with bracketed paste mode
killKill a running session
clearClear a finished session record
removeKill (if running) and remove session

Examples:

  • list all running processes
  • check session calm-harbor
  • kill the process swift-reef
  • send enter to session brisk-cove

Shell History

Examples:

  • SHELL action=clear_history
  • SHELL action=view_history

๐Ÿง  Shell History Provider

The plugin includes a SHELL_HISTORY provider that makes the following information available to the agent:

  • Recent Commands: Last 10 executed commands with their outputs
  • Current Working Directory: The current directory within the allowed path
  • Allowed Directory: The configured safe directory boundary
  • File Operations: Recent file creation, modification, and deletion operations

๐Ÿ”’ Security Considerations

Directory Restriction

All commands execute within SHELL_ALLOWED_DIRECTORY:

  • Attempts to navigate outside are blocked
  • Absolute paths outside the boundary are rejected
  • cd .. stops at the allowed directory root

Forbidden Commands

By default, these potentially dangerous commands are blocked:

  • Destructive: rm -rf /, rmdir
  • Permission changes: chmod 777, chown, chgrp
  • System operations: shutdown, reboot, halt, poweroff
  • Process control: kill -9, killall, pkill
  • User management: sudo rm -rf, su, passwd, useradd, userdel
  • Disk operations: format, fdisk, mkfs, dd if=/dev/zero, shred

Additional Safety Features

  • No Shell Expansion: Commands execute without dangerous shell interpretation
  • Timeout Protection: Commands auto-terminate after timeout
  • Command History: All executed commands are logged for audit
  • Path Traversal Protection: Blocks ../ and similar patterns

๐Ÿงช Development & Testing

TypeScript

bash
cd typescript
bun run build.ts     # Build
npx vitest           # Run tests

All Languages

bash
# From plugin root
bun run build          # Build TypeScript
bun run build:python   # Build Python
bun run build:rust     # Build Rust
bun run test           # Test TypeScript
bun run test:python    # Test Python
bun run test:rust      # Test Rust

๐Ÿ“– API Reference

CommandResult

FieldTypeDescription
successbooleanWhether the command executed successfully
stdoutstringStandard output from the command
stderrstringStandard error output
exitCodenumber | nullExit code of the command
errorstring | undefinedError message if command failed
executedInstringDirectory where command was executed

FileOperation

FieldTypeDescription
typeFileOperationTypeType of operation (create, write, read, delete, mkdir, move, copy)
targetstringTarget file/directory path
secondaryTargetstring | undefinedSecondary target for move/copy

ShellConfig

FieldTypeDefaultDescription
enabledbooleanfalseWhether shell is enabled
allowedDirectorystringcwdDirectory to restrict commands to
timeoutnumber30000Timeout in milliseconds
forbiddenCommandsstring[][...]List of forbidden commands
maxOutputCharsnumber200000Max output characters to capture
pendingMaxOutputCharsnumber200000Max pending output per stream
defaultBackgroundMsnumber10000Default background yield window
allowBackgroundbooleantrueAllow background execution

ProcessSession

FieldTypeDescription
idstringUnique session identifier (slug)
commandstringThe executed command
pidnumber | undefinedProcess ID
startedAtnumberStart timestamp
cwdstring | undefinedWorking directory
aggregatedstringAccumulated output
tailstringLast 2000 chars of output
exitedbooleanWhether process has exited
exitCodenumber | nullExit code (if exited)
exitSignalstring | number | nullExit signal (if killed)
truncatedbooleanWhether output was truncated
backgroundedbooleanWhether running in background

ExecResult

typescript
type ExecResult =
  | { status: "running"; sessionId: string; pid?: number; startedAt: number; cwd?: string; tail?: string }
  | { status: "completed" | "failed"; exitCode: number | null; durationMs: number; aggregated: string; cwd?: string; timedOut?: boolean; reason?: string }

ExecuteOptions

FieldTypeDescription
workdirstringWorking directory
envRecord<string, string>Additional environment variables
yieldMsnumberYield to background after this time
backgroundbooleanRun immediately in background
timeoutnumberTimeout in seconds
ptybooleanUse pseudo-terminal
conversationIdstringConversation ID for history tracking
scopeKeystringScope key for session isolation
sessionKeystringSession key for notifications
notifyOnExitbooleanNotify on background exit
onUpdate(session) => voidCallback for output updates

๐Ÿค Contributing

Contributions are welcome! Please ensure:

  1. All three language implementations stay in feature parity
  2. Tests pass for all languages
  3. Follow the code style of each language
  4. Update documentation as needed

๐Ÿ“ License

MIT - See LICENSE for details.