6.3 KiB
CLAUDE.md - Chat Module
This document provides guidance for Claude Code (claude.ai/code) when working with the Buster CLI chat implementation.
Architecture Overview
The Buster CLI chat module is a terminal-based interactive chat interface that connects to an AI agent with specialized data engineering capabilities. It's specifically designed for working with:
- DBT projects (data build tool)
- Buster semantic layer
- General data engineering tasks
Key Components
- BusterCliAgent: Core component that manages the AI connection and tool integration
- AppState: Maintains chat state, message history, and UI elements
- UI Layer: Terminal-based interface using Ratatui and Crossterm
- Tool Integration: Facilitates AI interaction with the filesystem, DBT commands, and Buster API
Code Organization
mod.rs
: Main module entry point and public APIargs.rs
: Command-line argument parsingconfig.rs
: Configuration managementlogic.rs
: Core chat execution logicstate.rs
: Chat session state managementui.rs
: Terminal UI implementationcompletion.rs
: Path and command autocompletion
AI Agent Tools
The agent is equipped with a set of tools similar to those available to Claude Code (claude.ai/code). These tools enable the agent to interact with the filesystem and execute commands. Many tools support batch operations by accepting arrays of inputs.
Core CLI Tools
-
BashTool (Bash)
- Parameters:
command
(string, required): Shell command to executedescription
(string, optional): Short description of commandtimeout
(number, optional): Timeout in milliseconds
- Returns: Terminal output (stdout/stderr combined)
- Notes: Executes commands via
sh -c
- Parameters:
-
ViewTool (View)
- Single file mode parameters:
file_path
(string, required): Path to fileoffset
(number, optional): Line number to start reading fromlimit
(number, optional): Maximum number of lines to read
- Multiple file mode parameters:
file_paths
(array, required): Array of paths to read
- Returns: File content with line numbers in cat -n format
- Notes: Can read multiple files in a single operation
- Single file mode parameters:
-
ReplaceTool (Replace)
- Parameters:
file_path
(string, required): Path to filecontent
(string, required): Content to write
- Returns: Success message
- Notes: Always overwrites existing files and creates parent directories if needed
- Parameters:
-
EditTool (Edit)
- Parameters:
file_path
(string, required): Path to fileold_string
(string, required): Text to replacenew_string
(string, required): New textexpected_replacements
(number, optional): Number of expected matches
- Returns: Success message
- Notes: Validates that the exact expected number of replacements are made
- Parameters:
-
LSTool (LS)
- Parameters:
path
(string, required): Directory to listignore
(array, optional): Glob patterns to ignore
- Returns: Directory listing (file/dir with names)
- Notes: Simple directory listing with ignore pattern support
- Parameters:
-
GrepTool (GrepTool)
- Parameters:
pattern
(string, required): Regex pattern to search forpath
(string, optional): Directory to search ininclude
(string, optional): File pattern to include
- Returns: Matches formatted as "file:line: content"
- Notes: Uses regex for searching with file pattern filtering
- Parameters:
-
GlobTool (GlobTool)
- Parameters:
pattern
(string, required): Glob pattern to matchpath
(string, optional): Directory to search from
- Returns: List of matching file paths sorted by modification time
- Notes: Uses glob patterns for file matching
- Parameters:
Implementation Notes
The tools are designed to work like Claude Code tools, with similar parameter names and output formats. This makes it easy to port code between the CLI agent and Claude Code.
Implementation Structure
Buster CLI tools follow a consistent object-oriented pattern and return simple string outputs instead of structured outputs:
// 1. Parameter definition with multi-mode support
#[derive(Serialize, Deserialize, Debug)]
pub struct ViewSingleParams {
file_path: String,
offset: Option<usize>,
limit: Option<usize>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ViewParams {
#[serde(flatten)]
single: Option<ViewSingleParams>,
#[serde(rename = "file_paths")]
multiple: Option<Vec<String>>,
}
// 2. Tool implementation
pub struct ViewTool {
agent: Arc<Agent>,
}
// 3. Constructor method
impl ViewTool {
pub fn new(agent: Arc<Agent>) -> Self {
Self { agent }
}
// Helper methods may be included
async fn read_single_file(&self, file_path: &str, offset: Option<usize>, limit: Option<usize>) -> Result<String, anyhow::Error> {
// Implementation...
}
}
// 4. ToolExecutor implementation
#[async_trait]
impl ToolExecutor for ViewTool {
type Params = ViewParams;
type Output = String; // Simple string output
fn get_name(&self) -> String {
"View".to_string() // Match Claude Code tool name
}
fn get_schema(&self) -> Value {
// JSON Schema definition with oneOf for multi-mode support
serde_json::json!({
"name": self.get_name(),
"description": "Reads a file from the local filesystem",
"parameters": {
"type": "object",
"oneOf": [
{
"properties": {
"file_path": { "type": "string" },
// ...
},
},
{
"properties": {
"file_paths": { "type": "array" },
// ...
},
}
]
}
})
}
async fn execute(&self, params: Self::Params, _tool_call_id: String) -> Result<Self::Output> {
// Handle different input modes
if let Some(file_paths) = params.multiple {
// Handle multiple files
} else if let Some(single) = params.single {
// Handle single file
} else {
// Error case
}
}
}