Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions crates/tui/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@
"SetupOperateNeedsActionSaved": "Operate/Fleet still needs action; recorded for setup report.",
"SetupHotbarBindingsLabel": "Hotbar bindings:",
"SetupHotbarActionsLabel": "Bindable actions:",
"SetupHotbarReviewHint": "Press H to customize slots; Enter records this Hotbar snapshot.",
"SetupHotbarReviewHint": "Enter records this Hotbar snapshot. Press H to customize slots.",
"SetupHotbarReviewed": "Hotbar setup state recorded.",
"SetupToolsMcpServersLabel": "MCP servers:",
"SetupToolsMcpSkillsLabel": "Skills:",
Expand All @@ -408,7 +408,7 @@
"SetupRemoteBridgesLabel": "Chat bridges:",
"SetupRemoteProvidersLabel": "Providers:",
"SetupRemoteModeLabel": "Remote mode:",
"SetupRemoteReviewHint": "Press R to preview; Enter records this Remote snapshot.",
"SetupRemoteReviewHint": "Enter records this Remote snapshot. Press R to preview.",
"SetupRemotePreviewTitle": "Remote runtime on-ramp",
"SetupRemoteReviewed": "Remote runtime on-ramp recorded.",
"SetupPersistenceHomeLabel": "Home:",
Expand All @@ -424,7 +424,7 @@
"SetupProviderModelReviewed": "Provider/model readiness recorded.",
"SetupProviderModelNeedsActionSaved": "Provider/model still needs action; recorded for setup report.",
"SetupRuntimePostureBoundary": "Runtime posture is enforced config; constitution guidance never changes it silently.",
"SetupRuntimePostureReviewHint": "Enter records this posture; press M for work mode or C for config.",
"SetupRuntimePostureReviewHint": "Enter records this Runtime snapshot. Press M for work mode or C for config.",
"SetupRuntimePostureReviewed": "Runtime posture reviewed; no config changed.",
"SetupRuntimePresetSelectedLabel": "Selected preset:",
"SetupRuntimePresetDiffLabel": "Config diff:",
Expand Down Expand Up @@ -486,7 +486,6 @@
"CtxMenuHelp": "Help",
"CtxMenuHelpDesc": "keybindings and commands",
"FanoutCounts": "{done} done · {running} running · {failed} failed · {pending} pending",
"ModePickerPrompt": "Choose how CodeWhale should operate:",
"AppModeAgent": "Act",
"AppModeAuto": "Auto",
"AppModeYolo": "YOLO (deprecated)",
Expand Down
1 change: 0 additions & 1 deletion crates/tui/locales/es-419.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@
"CtxMenuHelp": "Ayuda",
"CtxMenuHelpDesc": "atajos de teclado y comandos",
"FanoutCounts": "{done} completado · {running} ejecutando · {failed} falló · {pending} pendiente",
"ModePickerPrompt": "Elige cómo debe funcionar CodeWhale:",
"AppModeAgent": "Agente",
"AppModeAuto": "Automático",
"AppModeYolo": "YOLO",
Expand Down
1 change: 0 additions & 1 deletion crates/tui/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@
"CtxMenuHelp": "ヘルプ",
"CtxMenuHelpDesc": "キー操作とコマンド",
"FanoutCounts": "{done} 完了 · {running} 実行中 · {failed} 失敗 · {pending} 保留",
"ModePickerPrompt": "CodeWhale の動作方法を選択してください:",
"AppModeAgent": "エージェント",
"AppModeAuto": "自動",
"AppModeYolo": "YOLO",
Expand Down
1 change: 0 additions & 1 deletion crates/tui/locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@
"CtxMenuHelp": "Ajuda",
"CtxMenuHelpDesc": "atalhos de teclado e comandos",
"FanoutCounts": "{done} concluído · {running} em execução · {failed} falhou · {pending} pendente",
"ModePickerPrompt": "Escolha como o CodeWhale deve operar:",
"AppModeAgent": "Agente",
"AppModeAuto": "Automático",
"AppModeYolo": "YOLO",
Expand Down
1 change: 0 additions & 1 deletion crates/tui/locales/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@
"CtxMenuHelp": "Trợ giúp",
"CtxMenuHelpDesc": "phím tắt và lệnh",
"FanoutCounts": "{done} hoàn thành · {running} đang chạy · {failed} thất bại · {pending} chờ",
"ModePickerPrompt": "Chọn cách CodeWhale hoạt động:",
"AppModeAgent": "Tác nhân",
"AppModeAuto": "Tự động",
"AppModeYolo": "YOLO",
Expand Down
1 change: 0 additions & 1 deletion crates/tui/locales/zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@
"CtxMenuHelp": "帮助",
"CtxMenuHelpDesc": "快捷键和命令",
"FanoutCounts": "{done} 已完成 · {running} 运行中 · {failed} 失败 · {pending} 等待中",
"ModePickerPrompt": "选择 CodeWhale 的运行方式:",
"AppModeAgent": "智能体",
"AppModeAuto": "自动",
"AppModeYolo": "YOLO",
Expand Down
1 change: 0 additions & 1 deletion crates/tui/locales/zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"TranslationFailed": "翻譯失敗",
"FooterBalancePrefix": "餘額",
"FanoutCounts": "{done} 已完成 · {running} 運行中 · {failed} 失敗 · {pending} 等待中",
"ModePickerPrompt": "選擇 CodeWhale 的運作方式:",
"AppModeAgent": "智能體",
"AppModeAuto": "自動",
"AppModeYolo": "YOLO",
Expand Down
11 changes: 4 additions & 7 deletions crates/tui/src/localization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,7 @@ pub enum MessageId {
// Agent fanout card.
FanoutCounts,

// App mode picker (prompt, names, hints) and composer vim indicator.
ModePickerPrompt,
// App mode picker (names, hints) and composer vim indicator.
AppModeAgent,
AppModeAuto,
AppModeYolo,
Expand Down Expand Up @@ -1201,7 +1200,6 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[
MessageId::CtxMenuHelp,
MessageId::CtxMenuHelpDesc,
MessageId::FanoutCounts,
MessageId::ModePickerPrompt,
MessageId::AppModeAgent,
MessageId::AppModeAuto,
MessageId::AppModeYolo,
Expand Down Expand Up @@ -1624,11 +1622,10 @@ mod tests {

#[test]
fn mode_picker_strings_are_translated_in_non_english_locales() {
// The picker prompt and the three mode hints are full sentences; every
// shipped non-English locale must provide a real translation rather than
// leaking the English string through the fallback chain.
// The mode hints are full sentences; every shipped non-English locale
// must provide a real translation rather than leaking the English
// string through the fallback chain.
let sentences = [
MessageId::ModePickerPrompt,
MessageId::AppModeAgentHint,
MessageId::AppModeAutoHint,
MessageId::AppModePlanHint,
Expand Down
27 changes: 25 additions & 2 deletions crates/tui/src/tui/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,8 +835,13 @@ impl ExploringCell {
} else {
"running"
};
lines.push(render_tool_header_with_summary(
"Workspace",
// Search-only exploration cards read with the `find` verb so a
// completed grep renders `find done · Searching for …` instead of the
// incoherent `read done · Searching …` (#4145). Read/list or mixed
// cards keep the neutral `read` verb the Workspace card has always used.
let family = exploring_card_family(&self.entries);
lines.push(render_tool_header_with_family_and_summary(
family,
header_summary.as_deref(),
header_state,
status,
Expand Down Expand Up @@ -1710,6 +1715,24 @@ fn exploring_header_summary(entries: &[ExploringEntry]) -> Option<String> {
}
}

/// Choose the verb family for an exploring card's header. A card whose entries
/// are all searches reads with the `find` verb so the completed action agrees
/// with its `Searching for …` labels (#4145); every other exploration mix keeps
/// the neutral `read` verb the Workspace card uses. The search signal is the
/// English label prefix produced by `exploring_label` in `tool_routing`.
fn exploring_card_family(entries: &[ExploringEntry]) -> crate::tui::widgets::tool_card::ToolFamily {
use crate::tui::widgets::tool_card::ToolFamily;
let all_search = !entries.is_empty()
&& entries
.iter()
.all(|entry| entry.label.starts_with("Searching"));
if all_search {
ToolFamily::Find
} else {
ToolFamily::Read
}
}

fn render_compact_kv(label: &str, value: &str, style: Style, width: u16) -> Vec<Line<'static>> {
render_card_detail_line(Some(label.trim_end_matches(':')), value, style, width)
}
Expand Down
50 changes: 50 additions & 0 deletions crates/tui/src/tui/history/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,56 @@ fn generic_tool_cell_renders_rlm_with_rlm_label_not_swarm() {
);
}

#[test]
fn exploring_card_search_reads_as_find_not_read() {
// #4145: a completed grep grouped under the exploration card must not
// render `read done · Searching …`; the header verb has to agree with the
// `Searching for …` label.
let cell = super::ExploringCell {
entries: vec![super::ExploringEntry {
label: "Searching for `TranscriptScroll`".to_string(),
status: ToolStatus::Success,
}],
};
let header: String = cell.lines_with_motion(80, true)[0]
.spans
.iter()
.map(|s| s.content.as_ref())
.collect::<String>();
assert!(
header.contains("find done"),
"search card header should read `find done`: {header:?}"
);
assert!(
!header.contains("read done"),
"search card must not pair `read done` with a search label: {header:?}"
);
assert!(
header.contains("Searching for `TranscriptScroll`"),
"search label should remain intact: {header:?}"
);
}

#[test]
fn exploring_card_read_keeps_read_verb() {
// The fix only re-verbs search-only cards — a plain read stays `read`.
let cell = super::ExploringCell {
entries: vec![super::ExploringEntry {
label: "Reading src/foo.rs".to_string(),
status: ToolStatus::Success,
}],
};
let header: String = cell.lines_with_motion(80, true)[0]
.spans
.iter()
.map(|s| s.content.as_ref())
.collect::<String>();
assert!(
header.contains("read done"),
"read card header should read `read done`: {header:?}"
);
}

// === Reasoning treatment tests (v0.6.6 UI redesign) ===

#[test]
Expand Down
4 changes: 2 additions & 2 deletions crates/tui/src/tui/setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6137,7 +6137,7 @@ mod tests {
assert!(text.contains("configured_slots=2"));
assert!(text.contains("Bindable actions:"));
assert!(text.contains("13 bindable actions"));
assert!(text.contains("Press H to customize slots; Enter records this Hotbar snapshot."));
assert!(text.contains("Enter records this Hotbar snapshot. Press H to customize slots."));
}

#[test]
Expand Down Expand Up @@ -6271,7 +6271,7 @@ mod tests {
assert!(text.contains("feishu"));
assert!(text.contains("Remote mode:"));
assert!(text.contains("--apply not implemented"));
assert!(text.contains("Press R to preview; Enter records this Remote snapshot."));
assert!(text.contains("Enter records this Remote snapshot. Press R to preview."));
}

#[test]
Expand Down
Loading