@ondeinference / cli / commits / 5cb5838

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],