tui: show friendly location badge instead of truncated model dir
The fine-tune "done" screen rendered the raw absolute adapter path and the merged-model path, which truncate to gibberish (e.g. ".../Library/Group") in the narrow TUI fields. Show a friendly "[Onde Inference]" badge (plus the file name for the adapter) instead, reusing the same classification the GGUF detail screen already uses. Extracts the path-to-label logic from AdapterEntry::location_label into a reusable location_label_for_path() free function. Fixes #2 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Seto Elkahfi committed
Jun 27, 2026 at 08:00 UTC
5cb5838baeeefc0ac8bf966dc1625338eff400e3
2 files changed
+51
-31
src/app.rs
+35
-26
@@ -97,35 +97,44 @@ pub struct AdapterEntry {
97
pub kind: ArtifactKind,
98
}
99
100
-impl AdapterEntry {
101
- /// Classify the location of this artifact for display purposes.
102
- ///
103
- /// - `"Onde Inference"`: inside the shared App Group container
104
- /// - `"HF Cache"`: inside `~/.cache/huggingface/hub` or `$HF_HOME`
105
- /// - the raw path string: anything else, usually a custom or local export
106
- pub fn location_label(&self) -> String {
107
- let path_str = self.path.to_string_lossy();
100
+/// Classify a filesystem path into a short, human-friendly location label.
101
+///
102
+/// Long absolute paths (e.g. the App Group container) get truncated to
103
+/// gibberish in narrow TUI fields, so anywhere we'd otherwise print a raw
104
+/// path we show this label instead.
105
+///
106
+/// - `"Onde Inference"`: inside the shared App Group container
107
+/// - `"HF Cache"`: inside `~/.cache/huggingface/hub` or `$HF_HOME`
108
+/// - the parent directory string: anything else, usually a custom or local export
109
+pub fn location_label_for_path(path: &std::path::Path) -> String {
110
+ let path_str = path.to_string_lossy();
111
+
112
+ // App Group container (macOS)
113
+ if path_str.contains("group.com.ondeinference.apps") {
114
+ return "Onde Inference".to_string();
115
+ }
116
109
- // App Group container (macOS)
110
- if path_str.contains("group.com.ondeinference.apps") {
111
- return "Onde Inference".to_string();
112
- }
117
+ // Standard HF cache locations
118
+ if path_str.contains(".cache/huggingface/hub") {
119
+ return "HF Cache".to_string();
120
+ }
121
+ if let Ok(hf_home) = std::env::var("HF_HOME")
122
+ && path_str.starts_with(&hf_home)
123
+ {
124
+ return "HF Cache".to_string();
125
+ }
126
114
- // Standard HF cache locations
115
- if path_str.contains(".cache/huggingface/hub") {
116
- return "HF Cache".to_string();
117
- }
118
- if let Ok(hf_home) = std::env::var("HF_HOME")
119
- && path_str.starts_with(&hf_home)
120
- {
121
- return "HF Cache".to_string();
122
- }
127
+ // For custom or local paths, just show the directory.
128
+ path.parent()
129
+ .map(|p| p.to_string_lossy().to_string())
130
+ .unwrap_or_else(|| path_str.to_string())
131
+}
132
124
- // For custom or local paths, just show the directory.
125
- self.path
126
- .parent()
127
- .map(|p| p.to_string_lossy().to_string())
128
- .unwrap_or_else(|| path_str.to_string())
133
+impl AdapterEntry {
134
+ /// Classify the location of this artifact for display purposes.
135
+ /// See [`location_label_for_path`].
136
+ pub fn location_label(&self) -> String {
137
+ location_label_for_path(&self.path)
138
}
139
140
/// Whether this GGUF should show the upload-to-HuggingFace UI.
src/ui.rs
+16
-5
@@ -1860,10 +1860,21 @@ fn render_finetune_done(frame: &mut Frame, app: &App, adapter_path: &std::path::
1860
.style(Style::new().bg(C_SURFACE_STRONG));
1861
let path_inner = path_block.inner(rows[3]);
1862
frame.render_widget(path_block, rows[3]);
1863
+ // Show a friendly location badge plus the file name instead of the raw
1864
+ // absolute path, which truncates to gibberish in this narrow box.
1865
+ let adapter_file = adapter_path
1866
+ .file_name()
1867
+ .map(|n| n.to_string_lossy().to_string())
1868
+ .unwrap_or_default();
1869
frame.render_widget(
1864
- Paragraph::new(adapter_path.to_string_lossy().to_string())
1865
- .style(Style::new().fg(C_NEON))
1866
- .wrap(Wrap { trim: true }),
1870
+ Paragraph::new(Line::from(vec![
1871
+ Span::styled(
1872
+ format!("[{}]", crate::app::location_label_for_path(adapter_path)),
1873
+ Style::new().fg(C_NEON).bold(),
1874
+ ),
1875
+ Span::styled(format!(" {adapter_file}"), Style::new().fg(C_TEXT)),
1876
+ ]))
1877
+ .wrap(Wrap { trim: true }),
1878
path_inner,
1879
);
1880
@@ -1938,8 +1949,8 @@ fn render_merge_gguf_section(frame: &mut Frame, app: &App, area: Rect) {
1949
Span::styled("✓ ", Style::new().fg(C_NEON)),
1950
Span::styled("Merged → ", Style::new().fg(C_NEON).bold()),
1951
Span::styled(
1941
- output_path.to_string_lossy().to_string(),
1942
- Style::new().fg(C_TEXT),
1952
+ format!("[{}]", crate::app::location_label_for_path(output_path)),
1953
+ Style::new().fg(C_TEXT).bold(),
1954
),
1955
])),
1956
rows[0],