Skip to content
20 changes: 16 additions & 4 deletions crates/tui/src/tui/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3555,16 +3555,28 @@ impl FileActivitySummary {
pub fn compact_display(&self) -> Vec<String> {
let mut parts = Vec::new();
if self.files_read > 0 {
parts.push(format!("Read {} files", self.files_read));
parts.push(format!(
"Read {}",
tool_run::counted(self.files_read as usize, "file", "files")
Comment on lines +3559 to +3560

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Route activity labels through localization

When ui_locale is any shipped non-English locale, this receipt still renders English because compact_display receives no locale and the newly added verb/noun forms are literals; aggregate_activity_row calls it directly. This makes the grammar fix English-only and bypasses the complete locale packs, so pass the active locale and select translated MessageId values (including the singular/plural forms) instead.

AGENTS.md reference: crates/tui/AGENTS.md:L25-L26

Useful? React with 👍 / 👎.

));
}
if self.dirs_listed > 0 {
parts.push(format!("Listed {} directories", self.dirs_listed));
parts.push(format!(
"Listed {}",
tool_run::counted(self.dirs_listed as usize, "directory", "directories")
));
}
if self.patterns_searched > 0 {
parts.push(format!("Searched {} patterns", self.patterns_searched));
parts.push(format!(
"Searched {}",
tool_run::counted(self.patterns_searched as usize, "pattern", "patterns")
));
}
if self.files_written > 0 {
parts.push(format!("Wrote {} files", self.files_written));
parts.push(format!(
"Wrote {}",
tool_run::counted(self.files_written as usize, "file", "files")
));
}
parts
}
Expand Down
2 changes: 1 addition & 1 deletion crates/tui/src/tui/history/tool_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ fn activity_family_summary(run: &ToolRun, activities: &[ToolRunActivity]) -> Opt
(!families.is_empty()).then(|| families.join(", "))
}

fn counted(count: usize, singular: &str, plural: &str) -> String {
pub(super) fn counted(count: usize, singular: &str, plural: &str) -> String {
let noun = if count == 1 { singular } else { plural };
format!("{count} {noun}")
}
Expand Down
6 changes: 3 additions & 3 deletions crates/tui/src/tui/work_surface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -985,9 +985,9 @@ mod tests {
.find(|row| row.id.0 == "activity:aggregate")
.expect("aggregated activity row");
assert!(
activity.label.contains("Read 1 files")
&& activity.label.contains("Searched 1 patterns")
&& activity.label.contains("Wrote 1 files"),
activity.label.contains("Read 1 file ·")
&& activity.label.contains("Searched 1 pattern ·")
&& activity.label.ends_with("Wrote 1 file"),
"aggregated label: {}",
activity.label
);
Expand Down
4 changes: 2 additions & 2 deletions crates/tui/src/tui/work_surface/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4059,7 +4059,7 @@ mod tests {
#[test]
fn work_mutation_rows_keep_labels_privacy_and_all_inline_modes() {
let (label, detail, full) = mutation_activity_body(InlineDiffMode::Full);
assert_eq!(label, "Wrote 1 files");
assert_eq!(label, "Wrote 1 file");
assert_eq!(detail, "Updated <external file> · +1 -1");
assert!(full.contains("-old"), "{full}");
assert!(full.contains("+new"), "{full}");
Expand Down Expand Up @@ -4260,7 +4260,7 @@ mod tests {
.iter()
.find(|row| row.id.0 == "activity:aggregate")
.expect("aggregate activity");
assert!(activity_row.label.contains("Read 1 files"));
assert!(activity_row.label.contains("Read 1 file ·"));
assert!(activity_row.label.contains("Searched 2 patterns"));
assert!(!activity_row.label.contains("super_secret_pattern_xyz"));
assert!(!activity_row.detail.contains("super_secret_pattern_xyz"));
Expand Down
Loading