@elizaos/plugin-shell 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ElizaOS Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,352 @@
1
+ # @elizaos/plugin-shell
2
+
3
+ A secure shell command execution plugin for ElizaOS that allows agents to run terminal commands within a restricted directory with command history tracking.
4
+
5
+ ## 🚨 TL;DR - Quick Setup
6
+
7
+ **Just want your agent to execute commands? Here's the fastest path:**
8
+
9
+ 1. **Install the plugin**:
10
+ ```bash
11
+ cd your-eliza-project
12
+ bun add @elizaos/plugin-shell
13
+ ```
14
+
15
+ 2. **Create/update your `.env`**:
16
+ ```bash
17
+ SHELL_ENABLED=true
18
+ SHELL_ALLOWED_DIRECTORY=/path/to/safe/directory
19
+ ```
20
+
21
+ 3. **Add to your character**:
22
+ ```typescript
23
+ const character = {
24
+ // ... other config
25
+ plugins: ["@elizaos/plugin-shell"],
26
+ };
27
+ ```
28
+
29
+ 4. **Run:** `bun start`
30
+
31
+ ⚠️ **Security note:** The agent can ONLY execute commands within `SHELL_ALLOWED_DIRECTORY` - choose wisely!
32
+
33
+ ## Features
34
+
35
+ - βœ… **Cross-platform support**: Works on Linux, macOS, and Windows
36
+ - βœ… **Directory restriction**: Commands are restricted to a specified directory for safety
37
+ - βœ… **Command filtering**: Configurable list of forbidden commands
38
+ - βœ… **Timeout protection**: Automatic termination of long-running commands
39
+ - βœ… **Command history**: Tracks command execution history per conversation
40
+ - βœ… **File operation tracking**: Monitors file creation, modification, and deletion
41
+ - βœ… **Shell context provider**: Provides command history and working directory to agent context
42
+ - βœ… **Output capture**: Returns both stdout and stderr from executed commands
43
+ - βœ… **Safety first**: Disabled by default, requires explicit enabling
44
+
45
+ ## Prerequisites
46
+
47
+ - Node.js 20+ and bun installed
48
+ - ElizaOS project set up
49
+ - A designated safe directory for command execution
50
+
51
+ ## πŸš€ Quick Start
52
+
53
+ ### Step 1: Install the Plugin
54
+
55
+ ```bash
56
+ # Using bun (recommended)
57
+ bun add @elizaos/plugin-shell
58
+
59
+ # Using npm
60
+ npm install @elizaos/plugin-shell
61
+
62
+ # Using pnpm
63
+ pnpm add @elizaos/plugin-shell
64
+ ```
65
+
66
+ ### Step 2: Configure Environment Variables
67
+
68
+ Create or edit `.env` file in your project root:
69
+
70
+ ```bash
71
+ # REQUIRED: Enable the shell plugin (disabled by default for safety)
72
+ SHELL_ENABLED=true
73
+
74
+ # REQUIRED: Set the allowed directory (commands can only run here)
75
+ SHELL_ALLOWED_DIRECTORY=/home/user/safe-workspace
76
+
77
+ # OPTIONAL: Set custom timeout in milliseconds (default: 30000)
78
+ SHELL_TIMEOUT=60000
79
+
80
+ # OPTIONAL: Add additional forbidden commands (comma-separated)
81
+ SHELL_FORBIDDEN_COMMANDS=rm,mv,cp,chmod,chown,shutdown,reboot
82
+ ```
83
+
84
+ ### Step 3: Add to Your Character
85
+
86
+ ```typescript
87
+ import { Character } from "@elizaos/core";
88
+
89
+ const myCharacter: Character = {
90
+ name: "DevAssistant",
91
+ description: "A helpful development assistant",
92
+ plugins: ["@elizaos/plugin-shell"], // Add the shell plugin
93
+ // ... rest of your character config
94
+ };
95
+ ```
96
+
97
+ ### Step 4: Run Your Agent
98
+
99
+ ```bash
100
+ bun start
101
+ ```
102
+
103
+ Your agent can now execute shell commands! Try:
104
+ - "Show me what files are in this directory"
105
+ - "Run ls -la"
106
+ - "Create a file called hello.txt"
107
+ - "Check the git status"
108
+
109
+ ## πŸ“‹ Available Actions
110
+
111
+ ### EXECUTE_COMMAND
112
+
113
+ Executes ANY shell command within the allowed directory, including file operations.
114
+
115
+ **Examples:**
116
+ - `run ls -la` - List files with details
117
+ - `execute npm test` - Run tests
118
+ - `show me the current directory` - Execute pwd
119
+ - `create a file called hello.txt` - Creates a new file
120
+ - `write 'Hello World' to output.txt` - Write content to file
121
+ - `make a new directory called src` - Create directory
122
+ - `check git status` - Show git repository status
123
+
124
+ ### CLEAR_SHELL_HISTORY
125
+
126
+ Clears the command history for the current conversation.
127
+
128
+ **Examples:**
129
+ - `clear my shell history`
130
+ - `reset the terminal history`
131
+ - `delete command history`
132
+
133
+ ## 🧠 Shell History Provider
134
+
135
+ The plugin includes a `SHELL_HISTORY` provider that makes the following information available to the agent:
136
+
137
+ - **Recent Commands**: Last 10 executed commands with their outputs
138
+ - **Current Working Directory**: The current directory within the allowed path
139
+ - **Allowed Directory**: The configured safe directory boundary
140
+ - **File Operations**: Recent file creation, modification, and deletion operations
141
+
142
+ This context helps the agent understand previous commands and maintain continuity in conversations.
143
+
144
+ ## πŸ”’ Security Considerations
145
+
146
+ ### 1. Directory Restriction
147
+ The plugin enforces that ALL commands execute within `SHELL_ALLOWED_DIRECTORY`:
148
+ - Attempts to navigate outside are blocked
149
+ - Absolute paths outside the boundary are rejected
150
+ - `cd ..` stops at the allowed directory root
151
+
152
+ ### 2. Forbidden Commands
153
+ By default, these potentially dangerous commands are blocked:
154
+ - **Destructive**: `rm`, `rmdir`
155
+ - **Permission changes**: `chmod`, `chown`, `chgrp`
156
+ - **System operations**: `shutdown`, `reboot`, `halt`, `poweroff`
157
+ - **Process control**: `kill`, `killall`, `pkill`
158
+ - **User management**: `sudo`, `su`, `passwd`, `useradd`, `userdel`
159
+ - **Disk operations**: `format`, `fdisk`, `mkfs`, `dd`, `shred`
160
+
161
+ **Note:** Safe file operations ARE allowed: `touch`, `echo`, `cat`, `mkdir`, `ls`, etc.
162
+
163
+ ### 3. Additional Safety Features
164
+ - **No Shell Expansion**: Commands execute without dangerous shell interpretation
165
+ - **Timeout Protection**: Commands auto-terminate after timeout
166
+ - **Command History**: All executed commands are logged for audit
167
+ - **Path Traversal Protection**: Blocks `../` and similar patterns
168
+
169
+ ## 🎯 Common Use Cases
170
+
171
+ ### Development Assistant
172
+ ```bash
173
+ SHELL_ALLOWED_DIRECTORY=/home/user/projects
174
+ SHELL_TIMEOUT=120000 # 2 minutes for build commands
175
+ ```
176
+
177
+ Your agent can help with:
178
+ - Running tests and builds
179
+ - Git operations
180
+ - File management
181
+ - Code generation
182
+
183
+ ### System Monitor
184
+ ```bash
185
+ SHELL_ALLOWED_DIRECTORY=/var/log
186
+ SHELL_FORBIDDEN_COMMANDS=rm,mv,cp,chmod,chown # Read-only access
187
+ ```
188
+
189
+ Your agent can:
190
+ - Check log files
191
+ - Monitor system status
192
+ - Generate reports
193
+
194
+ ### Content Creator
195
+ ```bash
196
+ SHELL_ALLOWED_DIRECTORY=/home/user/content
197
+ ```
198
+
199
+ Your agent can:
200
+ - Create and organize files
201
+ - Process text files
202
+ - Manage content structure
203
+
204
+ ## πŸ”§ Troubleshooting
205
+
206
+ ### Plugin Not Working
207
+
208
+ **Checklist:**
209
+ - βœ… Is `SHELL_ENABLED=true` in your `.env`?
210
+ - βœ… Does `SHELL_ALLOWED_DIRECTORY` exist and is accessible?
211
+ - βœ… Is the plugin added to your character's `plugins` array?
212
+ - βœ… Check logs for "Shell service initialized"
213
+
214
+ ### "Shell plugin is disabled"
215
+
216
+ **Solution:** Set `SHELL_ENABLED=true` in your `.env` file
217
+
218
+ ### "Cannot navigate outside allowed directory"
219
+
220
+ **This is a security feature!** The agent cannot access files outside `SHELL_ALLOWED_DIRECTORY`.
221
+
222
+ **Solution:**
223
+ - Move your work to the allowed directory, OR
224
+ - Change `SHELL_ALLOWED_DIRECTORY` to include your work area
225
+
226
+ ### "Command is forbidden by security policy"
227
+
228
+ The command you're trying to run is in the forbidden list.
229
+
230
+ **Solution:**
231
+ - Use alternative safe commands, OR
232
+ - Remove the command from `SHELL_FORBIDDEN_COMMANDS` if you trust your environment
233
+
234
+ ### Command Not Found
235
+
236
+ The command might not be in the system PATH.
237
+
238
+ **Solution:**
239
+ - Use full paths: `/usr/bin/git` instead of `git`
240
+ - Ensure required tools are installed
241
+
242
+ ## πŸ“š Advanced Configuration
243
+
244
+ ### Per-Conversation History
245
+
246
+ Each conversation maintains its own:
247
+ - Command history (last 100 commands)
248
+ - Working directory context
249
+ - File operation tracking
250
+
251
+ This ensures privacy between different users/conversations.
252
+
253
+ ### Custom Timeout for Long Operations
254
+
255
+ ```bash
256
+ # For development environments with slow builds
257
+ SHELL_TIMEOUT=300000 # 5 minutes
258
+ ```
259
+
260
+ ### Minimal Forbidden Commands
261
+
262
+ ```bash
263
+ # For trusted environments
264
+ SHELL_FORBIDDEN_COMMANDS=shutdown,reboot
265
+ ```
266
+
267
+ ### Read-Only Mode
268
+
269
+ ```bash
270
+ # Block all write operations
271
+ SHELL_FORBIDDEN_COMMANDS=rm,rmdir,mv,cp,touch,mkdir,echo,cat,chmod,chown,dd
272
+ ```
273
+
274
+ ## πŸ§ͺ Development & Testing
275
+
276
+ ```bash
277
+ # Clone the repository
278
+ git clone https://github.com/elizaos/eliza.git
279
+ cd eliza/packages/plugin-shell
280
+
281
+ # Install dependencies
282
+ bun install
283
+
284
+ # Build the plugin
285
+ bun run build
286
+
287
+ # Run tests
288
+ bun test
289
+
290
+ # Run with debug logging
291
+ DEBUG=eliza:* bun start
292
+ ```
293
+
294
+ ### Testing Your Setup
295
+
296
+ 1. **Test Basic Commands**: Try `ls`, `pwd`, `echo test`
297
+ 2. **Test Restrictions**: Try `cd /` (should fail)
298
+ 3. **Test History**: Run commands then ask "what commands have I run?"
299
+ 4. **Test File Ops**: Create a file, then check history for tracking
300
+
301
+ ## πŸ“Š How It Works
302
+
303
+ ### Architecture
304
+ ```
305
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
306
+ β”‚ Your Agent │────▢│ Shell Plugin │────▢│ cross-spawn β”‚
307
+ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
308
+ β”‚ "run ls -la" β”‚ β”‚ - Path validationβ”‚ β”‚ - Secure exec β”‚
309
+ β”‚ β”‚ β”‚ - History track β”‚ β”‚ - No shell β”‚
310
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ - Timeout mgmt β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
311
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
312
+ ```
313
+
314
+ ### Execution Flow
315
+ 1. Agent receives command request
316
+ 2. Plugin validates command safety
317
+ 3. Checks directory boundaries
318
+ 4. Executes via `cross-spawn` (no shell)
319
+ 5. Captures output and errors
320
+ 6. Tracks in conversation history
321
+ 7. Returns formatted result
322
+
323
+ ## 🀝 Contributing
324
+
325
+ Contributions are welcome! Please:
326
+ 1. Check existing issues first
327
+ 2. Follow the code style
328
+ 3. Add tests for new features
329
+ 4. Update documentation
330
+
331
+ ### Running Plugin Tests
332
+
333
+ ```bash
334
+ # Run all tests
335
+ bun test
336
+
337
+ # Run specific test file
338
+ bun test src/__tests__/shellHistory.test.ts
339
+
340
+ # Run tests in watch mode
341
+ bun test --watch
342
+ ```
343
+
344
+ ## πŸ“– Additional Resources
345
+
346
+ - [ElizaOS Documentation](https://github.com/elizaos/eliza)
347
+ - [Security Best Practices](https://owasp.org/www-community/attacks/Command_Injection)
348
+ - [Cross-spawn Documentation](https://github.com/moxystudio/node-cross-spawn)
349
+
350
+ ## πŸ“ License
351
+
352
+ This plugin is part of the ElizaOS project. See the main repository for license information.
@@ -0,0 +1,106 @@
1
+ import { Service, IAgentRuntime, Action, Plugin } from '@elizaos/core';
2
+
3
+ interface CommandResult {
4
+ success: boolean;
5
+ stdout: string;
6
+ stderr: string;
7
+ exitCode: number | null;
8
+ error?: string;
9
+ executedIn: string;
10
+ }
11
+ interface CommandHistoryEntry {
12
+ command: string;
13
+ stdout: string;
14
+ stderr: string;
15
+ exitCode: number | null;
16
+ timestamp: number;
17
+ workingDirectory: string;
18
+ fileOperations?: FileOperation[];
19
+ }
20
+ interface FileOperation {
21
+ type: 'create' | 'write' | 'read' | 'delete' | 'mkdir' | 'move' | 'copy';
22
+ target: string;
23
+ secondaryTarget?: string;
24
+ }
25
+ declare class ShellService extends Service {
26
+ static serviceType: string;
27
+ private shellConfig;
28
+ private currentDirectory;
29
+ private commandHistory;
30
+ private maxHistoryPerConversation;
31
+ constructor(runtime: IAgentRuntime);
32
+ static start(runtime: IAgentRuntime): Promise<ShellService>;
33
+ stop(): Promise<void>;
34
+ get capabilityDescription(): string;
35
+ /**
36
+ * Executes a shell command within the allowed directory
37
+ * @param command The command to execute
38
+ * @param conversationId Optional conversation ID for history tracking
39
+ * @returns The command execution result
40
+ */
41
+ executeCommand(command: string, conversationId?: string): Promise<CommandResult>;
42
+ /**
43
+ * Handles the cd command to change directory within allowed bounds
44
+ * @param command The cd command
45
+ * @returns The command result
46
+ */
47
+ private handleCdCommand;
48
+ /**
49
+ * Runs a command using cross-spawn
50
+ * @param command The command to run
51
+ * @returns The command result
52
+ */
53
+ private runCommand;
54
+ /**
55
+ * Adds a command to the history
56
+ */
57
+ private addToHistory;
58
+ /**
59
+ * Detects file operations from a command
60
+ */
61
+ private detectFileOperations;
62
+ /**
63
+ * Resolves a path relative to the current working directory
64
+ */
65
+ private resolvePath;
66
+ /**
67
+ * Gets command history for a conversation
68
+ */
69
+ getCommandHistory(conversationId: string, limit?: number): CommandHistoryEntry[];
70
+ /**
71
+ * Clears command history for a conversation
72
+ */
73
+ clearCommandHistory(conversationId: string): void;
74
+ /**
75
+ * Gets the current working directory
76
+ * @param conversationId Optional conversation ID to get conversation-specific directory
77
+ * @returns The current directory path
78
+ */
79
+ getCurrentDirectory(_conversationId?: string): string;
80
+ /**
81
+ * Gets the allowed directory
82
+ * @returns The allowed directory path
83
+ */
84
+ getAllowedDirectory(): string;
85
+ }
86
+
87
+ declare const executeCommand: Action;
88
+
89
+ /**
90
+ * Shell plugin environment configuration
91
+ */
92
+ interface ShellConfig {
93
+ enabled: boolean;
94
+ allowedDirectory: string;
95
+ timeout: number;
96
+ forbiddenCommands: string[];
97
+ }
98
+ /**
99
+ * Loads and validates the shell plugin configuration
100
+ * @returns The validated configuration
101
+ */
102
+ declare function loadShellConfig(): ShellConfig;
103
+
104
+ declare const shellPlugin: Plugin;
105
+
106
+ export { type CommandResult, type ShellConfig, ShellService, shellPlugin as default, executeCommand, loadShellConfig, shellPlugin };