slug-code/src/tools/bash.rs
Bryan Ramos b8bf9029fe Initial Slug Code Rust implementation
Core features:
- OpenAI-compatible streaming provider (vLLM, Ollama, OpenAI, etc.)
- Agent loop with tool use (bash, read, write, edit, glob, grep)
- Permission system: ask/yolo/sandbox/allowEdits + glob patterns
- SLUG.md hierarchy loaded every turn (CLAUDE.md equivalent)
- Session persistence with --continue/--resume/--fork-session
- Hook system: 5 lifecycle events, command + prompt types
- Compaction: ToolResultTrim/Truncate strategies, /compact command
- Config via TOML, CLI args, env vars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 14:23:04 -04:00

56 lines
1.6 KiB
Rust

use super::{Tool, ToolDefinition};
use anyhow::Result;
use serde_json::Value;
use std::process::Command;
pub struct BashTool;
impl Tool for BashTool {
fn definition(&self) -> ToolDefinition {
ToolDefinition {
name: "bash".to_string(),
description: "Execute a bash command and return its output.".to_string(),
parameters: serde_json::json!({
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The bash command to execute"
}
},
"required": ["command"]
}),
}
}
fn execute(&self, args: &Value) -> Result<String> {
let command = args["command"]
.as_str()
.ok_or_else(|| anyhow::anyhow!("Missing 'command' argument"))?;
let output = Command::new("bash")
.arg("-c")
.arg(command)
.output()?;
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
let mut result = String::new();
if !stdout.is_empty() {
result.push_str(&stdout);
}
if !stderr.is_empty() {
if !result.is_empty() {
result.push('\n');
}
result.push_str("STDERR:\n");
result.push_str(&stderr);
}
if !output.status.success() {
result.push_str(&format!("\nExit code: {}", output.status.code().unwrap_or(-1)));
}
Ok(result)
}
}