normalize tool display; remove backticks (#1482)

This commit is contained in:
Gabriel Gordon-Hall
2025-12-09 15:50:17 +00:00
committed by GitHub
parent d0392e6d5e
commit 84d80659b3
9 changed files with 42 additions and 44 deletions

1
.gitignore vendored
View File

@@ -69,6 +69,7 @@ crates/executors/bindings
crates/utils/bindings
crates/services/bindings
crates/server/bindings
crates/remote/bindings
build-npm-package-codesign.sh

View File

@@ -8,7 +8,6 @@ use agent_client_protocol::{self as acp, SessionNotification};
use futures::StreamExt;
use regex::Regex;
use serde::Deserialize;
use tracing::{debug, trace};
use workspace_utils::msg_store::MsgStore;
pub use super::AcpAgentHarness;
@@ -38,7 +37,7 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
let mut stdout_lines = msg_store.stdout_lines_stream();
while let Some(Ok(line)) = stdout_lines.next().await {
if let Some(parsed) = AcpEventParser::parse_line(&line) {
trace!("Parsed ACP line: {:?}", parsed);
tracing::trace!("Parsed ACP line: {:?}", parsed);
match parsed {
AcpEvent::SessionStart(id) => {
if !stored_session_id {
@@ -207,7 +206,7 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
.map(|s| s.title.clone())
.or_else(|| Some("".to_string()));
}
trace!("Got tool call update: {:?}", update);
tracing::trace!("Got tool call update: {:?}", update);
if let Ok(tc) = agent_client_protocol::ToolCall::try_from(update.clone()) {
handle_tool_call(
&tc,
@@ -218,7 +217,7 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
&msg_store,
);
} else {
debug!("Failed to convert tool call update to ToolCall");
tracing::debug!("Failed to convert tool call update to ToolCall");
}
}
AcpEvent::User(_) | AcpEvent::Other(_) => (),
@@ -303,9 +302,10 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
// Prefer structured raw_output, else fallback to aggregated text content
let completed =
matches!(tc.status, agent_client_protocol::ToolCallStatus::Completed);
trace!(
tracing::trace!(
"Mapping execute tool call, completed: {}, command: {}",
completed, command
completed,
command
);
let tc_exit_status = match tc.status {
agent_client_protocol::ToolCallStatus::Completed => {
@@ -617,7 +617,7 @@ impl AcpEventParser {
return Some(acp_event);
}
debug!("Failed to parse ACP raw log {trimmed}");
tracing::debug!("Failed to parse ACP raw log {trimmed}");
None
}

View File

@@ -1196,11 +1196,11 @@ impl ClaudeLogProcessor {
worktree_path: &str,
) -> String {
match action_type {
ActionType::FileRead { path } => format!("`{path}`"),
ActionType::FileEdit { path, .. } => format!("`{path}`"),
ActionType::CommandRun { command, .. } => format!("`{command}`"),
ActionType::Search { query } => format!("`{query}`"),
ActionType::WebFetch { url } => format!("`{url}`"),
ActionType::FileRead { path } => path.to_string(),
ActionType::FileEdit { path, .. } => path.to_string(),
ActionType::CommandRun { command, .. } => command.to_string(),
ActionType::Search { query } => query.to_string(),
ActionType::WebFetch { url } => url.to_string(),
ActionType::TaskCreate { description } => {
if description.is_empty() {
"Task".to_string()
@@ -1232,13 +1232,13 @@ impl ClaudeLogProcessor {
if relative_path.is_empty() {
"List directory".to_string()
} else {
format!("List directory: `{relative_path}`")
format!("List directory: {relative_path}")
}
}
ClaudeToolData::Glob { pattern, path, .. } => {
if let Some(search_path) = path {
format!(
"Find files: `{}` in `{}`",
"Find files: `{}` in {}",
pattern,
make_path_relative(search_path, worktree_path)
)
@@ -1257,7 +1257,7 @@ impl ClaudeLogProcessor {
ClaudeToolData::CodebaseSearchAgent { query, path, .. } => {
match (query.as_ref(), path.as_ref()) {
(Some(q), Some(p)) if !q.is_empty() && !p.is_empty() => format!(
"Codebase search: `{}` in `{}`",
"Codebase search: `{}` in {}",
q,
make_path_relative(p, worktree_path)
),
@@ -1948,7 +1948,7 @@ mod tests {
"/tmp/test-worktree",
);
assert_eq!(result, "`**/*.ts`");
assert_eq!(result, "**/*.ts");
}
#[test]
@@ -1967,7 +1967,7 @@ mod tests {
"/tmp/test-worktree",
);
assert_eq!(result, "`*.js`");
assert_eq!(result, "*.js");
}
#[test]
@@ -1984,7 +1984,7 @@ mod tests {
"/tmp/test-worktree",
);
assert_eq!(result, "List directory: `components`");
assert_eq!(result, "List directory: components");
}
#[test]
@@ -2190,8 +2190,8 @@ mod tests {
let parsed: ClaudeJson = serde_json::from_str(bash_json).unwrap();
let entries = normalize(&parsed, "/tmp/work");
assert_eq!(entries.len(), 1);
// Content should display the command in backticks
assert_eq!(entries[0].content, "`echo hello`");
// Content should display the command
assert_eq!(entries[0].content, "echo hello");
// Task content should include description/prompt wrapped in backticks
let task_json = r#"{

View File

@@ -82,7 +82,7 @@ struct CommandState {
impl ToNormalizedEntry for CommandState {
fn to_normalized_entry(&self) -> NormalizedEntry {
let content = format!("`{}`", self.command);
let content = self.command.to_string();
NormalizedEntry {
timestamp: None,
@@ -894,7 +894,7 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
},
status: ToolStatus::Success,
},
content: format!("`{relative_path}`"),
content: relative_path.to_string(),
metadata: None,
},
);

View File

@@ -717,10 +717,7 @@ impl CursorToolCall {
match self {
CursorToolCall::Read { args, .. } => {
let path = make_path_relative(&args.path, worktree_path);
(
ActionType::FileRead { path: path.clone() },
format!("`{path}`"),
)
(ActionType::FileRead { path: path.clone() }, path)
}
CursorToolCall::Write { args, .. } => {
let path = make_path_relative(&args.path, worktree_path);
@@ -729,7 +726,7 @@ impl CursorToolCall {
path: path.clone(),
changes: vec![],
},
format!("`{path}`"),
path,
)
}
CursorToolCall::Edit { args, result, .. } => {
@@ -789,7 +786,7 @@ impl CursorToolCall {
path: path.clone(),
changes,
},
format!("`{path}`"),
path,
)
}
CursorToolCall::Delete { args, .. } => {
@@ -799,7 +796,7 @@ impl CursorToolCall {
path: path.clone(),
changes: vec![FileChange::Delete],
},
format!("`{path}`"),
path.to_string(),
)
}
CursorToolCall::Shell { args, .. } => {
@@ -809,7 +806,7 @@ impl CursorToolCall {
command: cmd.clone(),
result: None,
},
format!("`{cmd}`"),
cmd.to_string(),
)
}
CursorToolCall::Grep { args, .. } => {
@@ -818,7 +815,7 @@ impl CursorToolCall {
ActionType::Search {
query: pattern.clone(),
},
format!("`{pattern}`"),
pattern.to_string(),
)
}
CursorToolCall::SemSearch { args, .. } => {
@@ -827,7 +824,7 @@ impl CursorToolCall {
ActionType::Search {
query: query.clone(),
},
format!("`{query}`"),
query.to_string(),
)
}
CursorToolCall::Glob { args, .. } => {
@@ -838,7 +835,7 @@ impl CursorToolCall {
ActionType::Search {
query: pattern.clone(),
},
format!("Find files: `{pattern}` in `{path}`"),
format!("Find files: `{pattern}` in {path}"),
)
} else {
(
@@ -854,7 +851,7 @@ impl CursorToolCall {
let content = if path.is_empty() {
"List directory".to_string()
} else {
format!("List directory: `{path}`")
format!("List directory: {path}")
};
(
ActionType::Other {

View File

@@ -1026,7 +1026,7 @@ impl ToNormalizedEntry for FileReadState {
},
status: self.status.clone(),
},
content: format!("`{}`", self.path),
content: self.path.clone(),
metadata: None,
}
}
@@ -1052,7 +1052,7 @@ impl ToNormalizedEntry for FileEditState {
},
status: self.status.clone(),
},
content: format!("`{}`", self.path),
content: self.path.clone(),
metadata: None,
}
}
@@ -1094,7 +1094,7 @@ impl ToNormalizedEntry for CommandRunState {
},
status: self.status.clone(),
},
content: format!("`{}`", self.command),
content: self.command.clone(),
metadata: None,
}
}
@@ -1149,7 +1149,7 @@ impl ToNormalizedEntry for SearchState {
},
status: self.status.clone(),
},
content: format!("`{}`", self.query),
content: self.query.clone(),
metadata: None,
}
}
@@ -1173,7 +1173,7 @@ impl ToNormalizedEntry for WebFetchState {
},
status: self.status.clone(),
},
content: format!("`{}`", self.url),
content: self.url.clone(),
metadata: None,
}
}

View File

@@ -215,7 +215,7 @@ export default function DiffCard({
// Title row
const title = (
<p
className="text-xs font-mono overflow-x-auto flex-1"
className="text-sm font-mono overflow-x-auto flex-1"
style={{ color: 'hsl(var(--muted-foreground) / 0.7)' }}
>
<Icon className="h-3 w-3 inline mr-2" aria-hidden />

View File

@@ -516,9 +516,9 @@ const ToolCallCard: React.FC<{
{entryType && getEntryIcon(entryType)}
</span>
{showInlineSummary ? (
<span className="font-light">{inlineText}</span>
<span className="text-sm font-mono">{inlineText}</span>
) : (
<span className="font-normal">{label}</span>
<span className="text-sm font-mono">{label}</span>
)}
</span>
</HeaderWrapper>

View File

@@ -136,7 +136,7 @@ const FileChangeRenderer = ({
{icon}
<p
onClick={() => expandable && setExpanded()}
className="text-sm font-light overflow-x-auto flex-1 cursor-pointer"
className="text-sm font-mono overflow-x-auto flex-1 cursor-pointer"
>
{titleNode}
</p>