style: cargo fmt after parallel stream merges
This commit is contained in:
@@ -72,3 +72,4 @@ apps/
|
||||
# Claude Code runtime artifacts
|
||||
.claude/scheduled_tasks.lock
|
||||
.claude/worktrees/
|
||||
.worktrees/
|
||||
|
||||
@@ -3298,12 +3298,11 @@ impl Engine {
|
||||
"tool_id": tool_id.clone(),
|
||||
"tool_name": tool_name.clone(),
|
||||
}));
|
||||
let approval_key =
|
||||
crate::tools::approval_cache::build_approval_key(
|
||||
&tool_name,
|
||||
&tool_input,
|
||||
)
|
||||
.0;
|
||||
let approval_key = crate::tools::approval_cache::build_approval_key(
|
||||
&tool_name,
|
||||
&tool_input,
|
||||
)
|
||||
.0;
|
||||
let _ = self
|
||||
.tx_event
|
||||
.send(Event::ApprovalRequired {
|
||||
|
||||
@@ -319,9 +319,7 @@ pub enum ClientError {
|
||||
retryable: bool,
|
||||
},
|
||||
/// Generic internal error that doesn't fit a provider taxonomy.
|
||||
Internal {
|
||||
envelope: ErrorEnvelope,
|
||||
},
|
||||
Internal { envelope: ErrorEnvelope },
|
||||
}
|
||||
|
||||
impl ClientError {
|
||||
@@ -412,25 +410,15 @@ impl std::error::Error for ClientError {}
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum StreamError {
|
||||
/// Stream stalled — no chunk received within the idle timeout.
|
||||
Stall {
|
||||
timeout_secs: u64,
|
||||
},
|
||||
Stall { timeout_secs: u64 },
|
||||
/// Chunk decode / JSON parse failure.
|
||||
Decode {
|
||||
message: String,
|
||||
},
|
||||
Decode { message: String },
|
||||
/// Stream exceeded content size limit.
|
||||
Overflow {
|
||||
limit_bytes: usize,
|
||||
},
|
||||
Overflow { limit_bytes: usize },
|
||||
/// Stream exceeded wall‑clock duration limit.
|
||||
DurationLimit {
|
||||
limit_secs: u64,
|
||||
},
|
||||
DurationLimit { limit_secs: u64 },
|
||||
/// Transport error from the underlying SSE connection.
|
||||
Transport {
|
||||
message: String,
|
||||
},
|
||||
Transport { message: String },
|
||||
}
|
||||
|
||||
impl StreamError {
|
||||
@@ -439,29 +427,19 @@ impl StreamError {
|
||||
pub fn into_client_error(self) -> ClientError {
|
||||
match self {
|
||||
Self::Stall { timeout_secs } => {
|
||||
ClientError::stream(
|
||||
format!("Stream stalled after {timeout_secs}s idle"),
|
||||
true,
|
||||
)
|
||||
ClientError::stream(format!("Stream stalled after {timeout_secs}s idle"), true)
|
||||
}
|
||||
Self::Decode { message } => {
|
||||
ClientError::stream(format!("Stream decode error: {message}"), true)
|
||||
}
|
||||
Self::Overflow { limit_bytes } => {
|
||||
ClientError::stream(
|
||||
format!("Stream exceeded {limit_bytes} bytes limit"),
|
||||
false,
|
||||
)
|
||||
}
|
||||
Self::DurationLimit { limit_secs } => {
|
||||
ClientError::stream(
|
||||
format!("Stream exceeded {limit_secs}s duration limit"),
|
||||
false,
|
||||
)
|
||||
}
|
||||
Self::Transport { message } => {
|
||||
ClientError::stream(message, true)
|
||||
ClientError::stream(format!("Stream exceeded {limit_bytes} bytes limit"), false)
|
||||
}
|
||||
Self::DurationLimit { limit_secs } => ClientError::stream(
|
||||
format!("Stream exceeded {limit_secs}s duration limit"),
|
||||
false,
|
||||
),
|
||||
Self::Transport { message } => ClientError::stream(message, true),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,9 +134,8 @@ pub fn compose_prompt(mode: AppMode, personality: Personality) -> String {
|
||||
approval_prompt(mode).trim(),
|
||||
];
|
||||
|
||||
let mut out = String::with_capacity(
|
||||
parts.iter().map(|p| p.len()).sum::<usize>() + (parts.len() - 1) * 2,
|
||||
);
|
||||
let mut out =
|
||||
String::with_capacity(parts.iter().map(|p| p.len()).sum::<usize>() + (parts.len() - 1) * 2);
|
||||
for (i, part) in parts.iter().enumerate() {
|
||||
if i > 0 {
|
||||
out.push('\n');
|
||||
@@ -335,9 +334,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn each_mode_gets_correct_approval() {
|
||||
assert!(compose_prompt(AppMode::Agent, Personality::Calm).contains("Approval Policy: Suggest"));
|
||||
assert!(
|
||||
compose_prompt(AppMode::Agent, Personality::Calm).contains("Approval Policy: Suggest")
|
||||
);
|
||||
assert!(compose_prompt(AppMode::Yolo, Personality::Calm).contains("Approval Policy: Auto"));
|
||||
assert!(compose_prompt(AppMode::Plan, Personality::Calm).contains("Approval Policy: Never"));
|
||||
assert!(
|
||||
compose_prompt(AppMode::Plan, Personality::Calm).contains("Approval Policy: Never")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -3177,7 +3177,8 @@ mod tests {
|
||||
|
||||
harness
|
||||
.tx_event
|
||||
.send(EngineEvent::ApprovalRequired { approval_key: "test_key".to_string(),
|
||||
.send(EngineEvent::ApprovalRequired {
|
||||
approval_key: "test_key".to_string(),
|
||||
id: "tool_stale".to_string(),
|
||||
tool_name: "exec_command".to_string(),
|
||||
description: "stale approval".to_string(),
|
||||
|
||||
@@ -121,8 +121,11 @@ pub fn build_approval_key(tool_name: &str, input: &serde_json::Value) -> Approva
|
||||
let paths_hash = hash_patch_paths(input);
|
||||
format!("patch:{paths_hash}")
|
||||
}
|
||||
"exec_shell" | "exec_shell_wait" | "exec_shell_interact"
|
||||
| "exec_wait" | "exec_interact" => {
|
||||
"exec_shell"
|
||||
| "exec_shell_wait"
|
||||
| "exec_shell_interact"
|
||||
| "exec_wait"
|
||||
| "exec_interact" => {
|
||||
let prefix = command_prefix(input);
|
||||
format!("shell:{prefix}")
|
||||
}
|
||||
@@ -137,10 +140,7 @@ pub fn build_approval_key(tool_name: &str, input: &serde_json::Value) -> Approva
|
||||
|
||||
/// Extract the first three non‑flag tokens from the command string.
|
||||
fn command_prefix(input: &serde_json::Value) -> String {
|
||||
let cmd = input
|
||||
.get("command")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("");
|
||||
let cmd = input.get("command").and_then(|v| v.as_str()).unwrap_or("");
|
||||
let tokens: Vec<&str> = cmd
|
||||
.split_whitespace()
|
||||
.filter(|t| !t.starts_with('-'))
|
||||
@@ -190,10 +190,7 @@ fn hash_patch_paths(input: &serde_json::Value) -> String {
|
||||
|
||||
/// Parse the host portion from a URL input.
|
||||
fn parse_host(input: &serde_json::Value) -> String {
|
||||
let url = input
|
||||
.get("url")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("");
|
||||
let url = input.get("url").and_then(|v| v.as_str()).unwrap_or("");
|
||||
|
||||
if let Ok(parsed) = reqwest::Url::parse(url) {
|
||||
parsed.host_str().unwrap_or(url).to_string()
|
||||
|
||||
@@ -607,10 +607,7 @@ impl ToolSpec for McpToolAdapter {
|
||||
fn description(&self) -> &str {
|
||||
// McpTool.description is Option<String>; fall back to the
|
||||
// prefixed name when absent.
|
||||
self.tool
|
||||
.description
|
||||
.as_deref()
|
||||
.unwrap_or(&self.name)
|
||||
self.tool.description.as_deref().unwrap_or(&self.name)
|
||||
}
|
||||
|
||||
fn input_schema(&self) -> Value {
|
||||
@@ -645,18 +642,13 @@ impl ToolSpec for McpToolAdapter {
|
||||
!keep_loaded
|
||||
}
|
||||
|
||||
async fn execute(
|
||||
&self,
|
||||
input: Value,
|
||||
_context: &ToolContext,
|
||||
) -> Result<ToolResult, ToolError> {
|
||||
async fn execute(&self, input: Value, _context: &ToolContext) -> Result<ToolResult, ToolError> {
|
||||
let mut pool = self.pool.lock().await;
|
||||
let result = pool
|
||||
.call_tool(&self.name, input)
|
||||
.await
|
||||
.map_err(|e| ToolError::execution_failed(format!("MCP tool failed: {e}")))?;
|
||||
let content =
|
||||
serde_json::to_string_pretty(&result).unwrap_or_else(|_| result.to_string());
|
||||
let content = serde_json::to_string_pretty(&result).unwrap_or_else(|_| result.to_string());
|
||||
Ok(ToolResult::success(content))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,8 +668,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_request_new() {
|
||||
let params = json!({"path": "src/main.rs", "content": "test"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "write_file", "Write a file to disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"write_file",
|
||||
"Write a file to disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
|
||||
assert_eq!(request.id, "test-id");
|
||||
assert_eq!(request.tool_name, "write_file");
|
||||
@@ -682,8 +687,13 @@ mod tests {
|
||||
// Create params with a very long string
|
||||
let long_content = "x".repeat(300);
|
||||
let params = json!({"path": "src/main.rs", "content": long_content});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "write_file", "Write a file to disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"write_file",
|
||||
"Write a file to disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
|
||||
let display = request.params_display();
|
||||
// Should be truncated to around 200 chars
|
||||
@@ -694,8 +704,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_request_params_display_short() {
|
||||
let params = json!({"path": "src/main.rs"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "read_file", "Read a file from disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"read_file",
|
||||
"Read a file from disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
|
||||
let display = request.params_display();
|
||||
assert!(display.contains("src/main.rs"));
|
||||
@@ -704,7 +719,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_request_derives_impact_summary() {
|
||||
let params = json!({"cmd": "cargo test", "workdir": "/tmp/project"});
|
||||
let request = ApprovalRequest::new("test-id", "exec_shell", "Run a shell command", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"exec_shell",
|
||||
"Run a shell command",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
|
||||
assert_eq!(request.category, ToolCategory::Shell);
|
||||
assert!(
|
||||
@@ -728,8 +749,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_view_initial_state() {
|
||||
let params = json!({"path": "src/main.rs"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "read_file", "Read a file from disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"read_file",
|
||||
"Read a file from disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
let view = ApprovalView::new(request.clone());
|
||||
|
||||
assert_eq!(view.selected, 0);
|
||||
@@ -739,8 +765,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_view_navigation() {
|
||||
let params = json!({"path": "src/main.rs"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "read_file", "Read a file from disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"read_file",
|
||||
"Read a file from disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
let mut view = ApprovalView::new(request);
|
||||
|
||||
// Initially at 0
|
||||
@@ -768,8 +799,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_view_keybindings_decisions() {
|
||||
let params = json!({"path": "src/main.rs"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "read_file", "Read a file from disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"read_file",
|
||||
"Read a file from disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
let mut view = ApprovalView::new(request.clone());
|
||||
|
||||
// Test 'y' -> Approved
|
||||
@@ -819,8 +855,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_view_enter_uses_selected_option() {
|
||||
let params = json!({"path": "src/main.rs"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "read_file", "Read a file from disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"read_file",
|
||||
"Read a file from disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
let mut view = ApprovalView::new(request);
|
||||
|
||||
// Navigate to index 2 (Denied)
|
||||
@@ -842,8 +883,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_view_navigation_keys() {
|
||||
let params = json!({"path": "src/main.rs"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "read_file", "Read a file from disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"read_file",
|
||||
"Read a file from disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
let mut view = ApprovalView::new(request);
|
||||
|
||||
// Test Up arrow
|
||||
@@ -866,8 +912,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_view_view_params() {
|
||||
let params = json!({"path": "src/main.rs", "content": "test"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "read_file", "Read a file from disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"read_file",
|
||||
"Read a file from disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
let mut view = ApprovalView::new(request.clone());
|
||||
|
||||
// Test 'v' to view params
|
||||
@@ -889,8 +940,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_approval_view_current_decision_mapping() {
|
||||
let params = json!({"path": "src/main.rs"});
|
||||
let request =
|
||||
ApprovalRequest::new("test-id", "read_file", "Read a file from disk", ¶ms, "test_key");
|
||||
let request = ApprovalRequest::new(
|
||||
"test-id",
|
||||
"read_file",
|
||||
"Read a file from disk",
|
||||
¶ms,
|
||||
"test_key",
|
||||
);
|
||||
let mut view = ApprovalView::new(request);
|
||||
|
||||
// Index 0 -> Approved
|
||||
|
||||
@@ -771,8 +771,9 @@ async fn run_event_loop(
|
||||
description,
|
||||
approval_key,
|
||||
} => {
|
||||
let session_approved = app.approval_session_approved.contains(&approval_key)
|
||||
|| app.approval_session_approved.contains(&tool_name);
|
||||
let session_approved =
|
||||
app.approval_session_approved.contains(&approval_key)
|
||||
|| app.approval_session_approved.contains(&tool_name);
|
||||
if session_approved || app.approval_mode == ApprovalMode::Auto {
|
||||
log_sensitive_event(
|
||||
"tool.approval.auto_approve",
|
||||
@@ -809,8 +810,13 @@ async fn run_event_loop(
|
||||
}
|
||||
|
||||
// Create approval request and show overlay
|
||||
let request =
|
||||
ApprovalRequest::new(&id, &tool_name, &description, &tool_input, &approval_key);
|
||||
let request = ApprovalRequest::new(
|
||||
&id,
|
||||
&tool_name,
|
||||
&description,
|
||||
&tool_input,
|
||||
&approval_key,
|
||||
);
|
||||
log_sensitive_event(
|
||||
"tool.approval.prompted",
|
||||
serde_json::json!({
|
||||
|
||||
Reference in New Issue
Block a user