|
1 | | -# ElizaOS Plugin |
| 1 | +# ElizaOS Shell Plugin |
2 | 2 |
|
3 | | -This is an ElizaOS plugin built with the official plugin starter template. |
| 3 | +A powerful shell execution plugin for ElizaOS that provides agents with a virtual shell environment. This plugin enables agents to execute shell commands, navigate directories, and maintain command history across conversations. |
4 | 4 |
|
5 | | -## Getting Started |
| 5 | +## Features |
6 | 6 |
|
7 | | -```bash |
8 | | -# Create a new plugin (automatically adds "plugin-" prefix) |
9 | | -elizaos create -t plugin solana |
10 | | -# This creates: plugin-solana |
11 | | -# Dependencies are automatically installed and built |
| 7 | +- **Persistent Shell State**: Maintains working directory and environment across command executions |
| 8 | +- **Natural Language Support**: Agents can describe commands in natural language (e.g., "list all files in the current directory") |
| 9 | +- **Command History**: Tracks all executed commands and their outputs for context |
| 10 | +- **File Operation Tracking**: Monitors file creations, modifications, and deletions |
| 11 | +- **Security Features**: Audit trails and safe command execution |
| 12 | +- **Smart Wildcard Handling**: Automatically quotes wildcards for find and grep commands |
12 | 13 |
|
13 | | -# Navigate to the plugin directory |
14 | | -cd plugin-solana |
| 14 | +## Installation |
15 | 15 |
|
16 | | -# Start development immediately |
17 | | -elizaos dev |
| 16 | +```bash |
| 17 | +npm install @elizaos/plugin-shell |
18 | 18 | ``` |
19 | 19 |
|
20 | | -## Development |
| 20 | +## Usage |
21 | 21 |
|
22 | | -```bash |
23 | | -# Start development with hot-reloading (recommended) |
24 | | -elizaos dev |
| 22 | +Add the plugin to your ElizaOS agent configuration: |
25 | 23 |
|
26 | | -# OR start without hot-reloading |
27 | | -elizaos start |
28 | | -# Note: When using 'start', you need to rebuild after changes: |
29 | | -# bun run build |
| 24 | +```typescript |
| 25 | +import { shellPlugin } from '@elizaos/plugin-shell'; |
30 | 26 |
|
31 | | -# Test the plugin |
32 | | -elizaos test |
| 27 | +const agent = new Agent({ |
| 28 | + plugins: [shellPlugin], |
| 29 | + // ... other configuration |
| 30 | +}); |
33 | 31 | ``` |
34 | 32 |
|
35 | | -## Testing |
| 33 | +## Actions |
36 | 34 |
|
37 | | -ElizaOS provides a comprehensive testing structure for plugins: |
| 35 | +### runShellCommand |
38 | 36 |
|
39 | | -### Test Structure |
40 | | - |
41 | | -- **Component Tests** (`__tests__/` directory): |
42 | | - |
43 | | - - **Unit Tests**: Test individual functions/classes in isolation |
44 | | - - **Integration Tests**: Test how components work together |
45 | | - - Run with: `elizaos test component` |
| 37 | +Executes shell commands with persistent state management. |
46 | 38 |
|
47 | | -- **End-to-End Tests** (`e2e/` directory): |
| 39 | +**Examples:** |
| 40 | +```typescript |
| 41 | +// Direct command |
| 42 | +"Run the command: ls -la" |
48 | 43 |
|
49 | | - - Test the plugin within a full ElizaOS runtime |
50 | | - - Run with: `elizaos test e2e` |
| 44 | +// Natural language |
| 45 | +"Show me all TypeScript files in the src directory" |
| 46 | +"Create a new directory called 'test-output'" |
| 47 | +"Check what's in the package.json file" |
| 48 | +``` |
51 | 49 |
|
52 | | -- **Running All Tests**: |
53 | | - - `elizaos test` runs both component and e2e tests |
| 50 | +**Features:** |
| 51 | +- Maintains working directory between commands |
| 52 | +- Supports pipes, redirects, and command chaining |
| 53 | +- Handles wildcards intelligently |
| 54 | +- Tracks file operations |
54 | 55 |
|
55 | | -### Writing Tests |
| 56 | +### clearShellHistory |
56 | 57 |
|
57 | | -Component tests use Vitest: |
| 58 | +Clears the command history for the current conversation. |
58 | 59 |
|
| 60 | +**Example:** |
59 | 61 | ```typescript |
60 | | -// Unit test example (__tests__/plugin.test.ts) |
61 | | -describe('Plugin Configuration', () => { |
62 | | - it('should have correct plugin metadata', () => { |
63 | | - expect(starterPlugin.name).toBe('plugin-starter'); |
64 | | - }); |
65 | | -}); |
66 | | - |
67 | | -// Integration test example (__tests__/integration.test.ts) |
68 | | -describe('Integration: HelloWorld Action with StarterService', () => { |
69 | | - it('should handle HelloWorld action with StarterService', async () => { |
70 | | - // Test interactions between components |
71 | | - }); |
72 | | -}); |
| 62 | +"Clear the shell history" |
73 | 63 | ``` |
74 | 64 |
|
75 | | -E2E tests use ElizaOS test interface: |
| 65 | +### killAutonomous |
76 | 66 |
|
77 | | -```typescript |
78 | | -// E2E test example (e2e/starter-plugin.test.ts) |
79 | | -export class StarterPluginTestSuite implements TestSuite { |
80 | | - name = 'plugin_starter_test_suite'; |
81 | | - tests = [ |
82 | | - { |
83 | | - name: 'example_test', |
84 | | - fn: async (runtime) => { |
85 | | - // Test plugin in a real runtime |
86 | | - }, |
87 | | - }, |
88 | | - ]; |
89 | | -} |
| 67 | +Stops any long-running or background processes. |
90 | 68 |
|
91 | | -export default new StarterPluginTestSuite(); |
| 69 | +**Example:** |
| 70 | +```typescript |
| 71 | +"Stop the autonomous process" |
92 | 72 | ``` |
93 | 73 |
|
94 | | -The test utilities in `__tests__/test-utils.ts` provide mock objects and setup functions to simplify writing tests. |
| 74 | +## Configuration |
95 | 75 |
|
96 | | -## Publishing & Continuous Development |
| 76 | +The plugin works out of the box with no required configuration. Optional settings can be provided: |
97 | 77 |
|
98 | | -### Initial Setup |
| 78 | +```typescript |
| 79 | +const shellPlugin = { |
| 80 | + name: "shell", |
| 81 | + description: "Shell command execution with state management", |
| 82 | + services: [new ShellService()], |
| 83 | + actions: [runShellCommandAction, clearShellHistoryAction, killAutonomousAction], |
| 84 | + providers: [shellProvider], |
| 85 | +}; |
| 86 | +``` |
99 | 87 |
|
100 | | -Before publishing your plugin, ensure you meet these requirements: |
| 88 | +## Shell Service |
101 | 89 |
|
102 | | -1. **npm Authentication** |
| 90 | +The `ShellService` class provides the core functionality: |
103 | 91 |
|
104 | | - ```bash |
105 | | - npm login |
106 | | - ``` |
| 92 | +- **Persistent Working Directory**: Each conversation maintains its own working directory |
| 93 | +- **Command Execution**: Safe execution with proper error handling |
| 94 | +- **History Management**: Tracks commands, outputs, and file operations |
| 95 | +- **State Persistence**: Maintains shell state across agent interactions |
107 | 96 |
|
108 | | -2. **GitHub Repository** |
| 97 | +## Security Considerations |
109 | 98 |
|
110 | | - - Create a public GitHub repository for this plugin |
111 | | - - Add the 'elizaos-plugins' topic to the repository |
112 | | - - Use 'main' as the default branch |
| 99 | +- Commands are executed with the permissions of the ElizaOS process |
| 100 | +- All commands are logged in the audit trail |
| 101 | +- Special characters are properly escaped |
| 102 | +- Consider running ElizaOS in a sandboxed environment for production use |
113 | 103 |
|
114 | | -3. **Required Assets** |
115 | | - - Add images to the `images/` directory: |
116 | | - - `logo.jpg` (400x400px square, <500KB) |
117 | | - - `banner.jpg` (1280x640px, <1MB) |
| 104 | +## Development |
118 | 105 |
|
119 | | -### Initial Publishing |
| 106 | +### Building |
120 | 107 |
|
121 | 108 | ```bash |
122 | | -# Test your plugin meets all requirements |
123 | | -elizaos publish --test |
124 | | - |
125 | | -# Publish to npm + GitHub + registry (recommended) |
126 | | -elizaos publish |
| 109 | +npm run build |
127 | 110 | ``` |
128 | 111 |
|
129 | | -This command will: |
| 112 | +### Testing |
130 | 113 |
|
131 | | -- Publish your plugin to npm for easy installation |
132 | | -- Create/update your GitHub repository |
133 | | -- Submit your plugin to the ElizaOS registry for discoverability |
| 114 | +The plugin includes comprehensive test coverage: |
134 | 115 |
|
135 | | -### Continuous Development & Updates |
| 116 | +```bash |
| 117 | +# Run all tests |
| 118 | +npm test |
136 | 119 |
|
137 | | -**Important**: After your initial publish with `elizaos publish`, all future updates should be done using standard npm and git workflows, not the ElizaOS CLI. |
| 120 | +# Run unit tests only |
| 121 | +npm run test:unit |
138 | 122 |
|
139 | | -#### Standard Update Workflow |
| 123 | +# Run E2E tests only |
| 124 | +npm run test:e2e |
140 | 125 |
|
141 | | -1. **Make Changes** |
| 126 | +# Run tests in watch mode |
| 127 | +npm run test:watch |
| 128 | +``` |
142 | 129 |
|
143 | | - ```bash |
144 | | - # Edit your plugin code |
145 | | - elizaos dev # Test locally with hot-reload |
146 | | - ``` |
| 130 | +### Test Structure |
147 | 131 |
|
148 | | -2. **Test Your Changes** |
| 132 | +- **Unit Tests** (`src/tests/shell.test.ts`): Test individual components in isolation |
| 133 | +- **E2E Tests** (`src/tests/e2e/`): Test real shell interactions |
| 134 | + - `shell-basic.ts`: Basic command execution |
| 135 | + - `shell-stateful.ts`: State persistence and directory navigation |
| 136 | + - `shell-advanced.ts`: Complex commands and workflows |
| 137 | + - `shell-security.ts`: Security and edge cases |
149 | 138 |
|
150 | | - ```bash |
151 | | - # Run all tests |
152 | | - elizaos test |
| 139 | +## Examples |
153 | 140 |
|
154 | | - # Run specific test types if needed |
155 | | - elizaos test component # Component tests only |
156 | | - elizaos test e2e # E2E tests only |
157 | | - ``` |
| 141 | +### Basic File Operations |
| 142 | +```typescript |
| 143 | +// List files |
| 144 | +"Show me what files are in this directory" |
158 | 145 |
|
159 | | -3. **Update Version** |
| 146 | +// Create a file |
| 147 | +"Create a file called README.md with the content 'Hello World'" |
160 | 148 |
|
161 | | - ```bash |
162 | | - # Patch version (bug fixes): 1.0.0 → 1.0.1 |
163 | | - npm version patch |
| 149 | +// Read a file |
| 150 | +"What's in the config.json file?" |
164 | 151 |
|
165 | | - # Minor version (new features): 1.0.1 → 1.1.0 |
166 | | - npm version minor |
| 152 | +// Delete a file |
| 153 | +"Remove the temporary.txt file" |
| 154 | +``` |
167 | 155 |
|
168 | | - # Major version (breaking changes): 1.1.0 → 2.0.0 |
169 | | - npm version major |
170 | | - ``` |
| 156 | +### Directory Navigation |
| 157 | +```typescript |
| 158 | +// Change directory |
| 159 | +"Go to the src directory" |
171 | 160 |
|
172 | | -4. **Publish to npm** |
| 161 | +// Check current location |
| 162 | +"Where am I?" |
173 | 163 |
|
174 | | - ```bash |
175 | | - npm publish |
176 | | - ``` |
| 164 | +// Create and navigate |
| 165 | +"Create a new folder called 'output' and go into it" |
| 166 | +``` |
177 | 167 |
|
178 | | -5. **Push to GitHub** |
179 | | - ```bash |
180 | | - git push origin main |
181 | | - git push --tags # Push version tags |
182 | | - ``` |
| 168 | +### Complex Operations |
| 169 | +```typescript |
| 170 | +// Find files |
| 171 | +"Find all JavaScript files in the project" |
183 | 172 |
|
184 | | -#### Why Use Standard Workflows? |
| 173 | +// Search content |
| 174 | +"Search for 'TODO' in all TypeScript files" |
185 | 175 |
|
186 | | -- **npm publish**: Directly updates your package on npm registry |
187 | | -- **git push**: Updates your GitHub repository with latest code |
188 | | -- **Automatic registry updates**: The ElizaOS registry automatically syncs with npm, so no manual registry updates needed |
189 | | -- **Standard tooling**: Uses familiar npm/git commands that work with all development tools |
| 176 | +// Pipe commands |
| 177 | +"Count how many TypeScript files are in the src directory" |
| 178 | +``` |
190 | 179 |
|
191 | | -### Alternative Publishing Options (Initial Only) |
| 180 | +## API Reference |
192 | 181 |
|
193 | | -```bash |
194 | | -# Publish to npm only (skip GitHub and registry) |
195 | | -elizaos publish --npm |
| 182 | +### ShellService |
196 | 183 |
|
197 | | -# Publish but skip registry submission |
198 | | -elizaos publish --skip-registry |
199 | | - |
200 | | -# Generate registry files locally without publishing |
201 | | -elizaos publish --dry-run |
| 184 | +```typescript |
| 185 | +class ShellService { |
| 186 | + async executeCommand(command: string, workingDir?: string): Promise<ShellCommandResult> |
| 187 | + async getCommandHistory(conversationId?: string): Promise<CommandHistoryEntry[]> |
| 188 | + async clearCommandHistory(conversationId?: string): Promise<void> |
| 189 | + getCurrentWorkingDirectory(conversationId?: string): string |
| 190 | +} |
202 | 191 | ``` |
203 | 192 |
|
204 | | -## Configuration |
| 193 | +### Types |
| 194 | + |
| 195 | +```typescript |
| 196 | +interface ShellCommandResult { |
| 197 | + output: string; |
| 198 | + error: string | null; |
| 199 | + exitCode: number; |
| 200 | + executedCommand: string; |
| 201 | + workingDirectory: string; |
| 202 | +} |
205 | 203 |
|
206 | | -The `agentConfig` section in `package.json` defines the parameters your plugin requires: |
207 | | - |
208 | | -```json |
209 | | -"agentConfig": { |
210 | | - "pluginType": "elizaos:plugin:1.0.0", |
211 | | - "pluginParameters": { |
212 | | - "API_KEY": { |
213 | | - "type": "string", |
214 | | - "description": "API key for the service" |
215 | | - } |
216 | | - } |
| 204 | +interface CommandHistoryEntry { |
| 205 | + command: string; |
| 206 | + output: string; |
| 207 | + error: string | null; |
| 208 | + exitCode: number; |
| 209 | + timestamp: Date; |
| 210 | + workingDirectory: string; |
| 211 | + fileOperations?: FileOperation[]; |
217 | 212 | } |
218 | 213 | ``` |
219 | 214 |
|
220 | | -Customize this section to match your plugin's requirements. |
| 215 | +## Contributing |
| 216 | + |
| 217 | +Contributions are welcome! Please ensure: |
| 218 | + |
| 219 | +1. All tests pass (`npm test`) |
| 220 | +2. Code follows the existing style |
| 221 | +3. New features include tests |
| 222 | +4. Documentation is updated |
| 223 | + |
| 224 | +## License |
221 | 225 |
|
222 | | -## Documentation |
| 226 | +MIT |
223 | 227 |
|
224 | | -Provide clear documentation about: |
| 228 | +## Support |
225 | 229 |
|
226 | | -- What your plugin does |
227 | | -- How to use it |
228 | | -- Required API keys or credentials |
229 | | -- Example usage |
230 | | -- Version history and changelog |
| 230 | +For issues and feature requests, please use the GitHub issue tracker. |
0 commit comments