Skip to content

Commit 9cb7750

Browse files
committed
MCP: Show dir sizes in state resource
- Directories now show `recursiveSize` in `cmdr://state` file listings, matching the format position of file sizes - Added `recursiveSize` to `PaneFileEntry` interface and `buildMcpFileList()` mapping
1 parent d900b1c commit 9cb7750

5 files changed

Lines changed: 35 additions & 0 deletions

File tree

apps/desktop/src-tauri/src/mcp/pane_state.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ pub struct FileEntry {
2626
#[serde(skip_serializing_if = "Option::is_none")]
2727
pub size: Option<u64>,
2828
#[serde(skip_serializing_if = "Option::is_none")]
29+
pub recursive_size: Option<u64>,
30+
#[serde(skip_serializing_if = "Option::is_none")]
2931
pub modified: Option<String>,
3032
}
3133

@@ -164,6 +166,7 @@ mod tests {
164166
path: "/tmp/test.txt".to_string(),
165167
is_directory: false,
166168
size: Some(100),
169+
recursive_size: None,
167170
modified: None,
168171
}],
169172
cursor_index: 0,

apps/desktop/src-tauri/src/mcp/resources.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ fn format_file_compact(
7676
if include_details {
7777
if let Some(size) = file.size {
7878
parts.push(format_size(size));
79+
} else if let Some(recursive_size) = file.recursive_size {
80+
parts.push(format_size(recursive_size));
7981
}
8082
if let Some(ref modified) = file.modified {
8183
parts.push(modified.clone());
@@ -158,6 +160,8 @@ fn build_pane_yaml(state: &PaneState, indent: &str) -> String {
158160
lines.push(format!("{} name: {}", indent, cursor_file.name));
159161
if let Some(size) = cursor_file.size {
160162
lines.push(format!("{} size: {}", indent, format_size(size)));
163+
} else if let Some(recursive_size) = cursor_file.recursive_size {
164+
lines.push(format!("{} size: {}", indent, format_size(recursive_size)));
161165
}
162166
if let Some(ref modified) = cursor_file.modified {
163167
lines.push(format!("{} modified: {}", indent, modified));
@@ -542,6 +546,7 @@ mod tests {
542546
path: "/tmp/test.txt".to_string(),
543547
is_directory: false,
544548
size: Some(1024),
549+
recursive_size: None,
545550
modified: Some("2024-01-15".to_string()),
546551
};
547552

@@ -567,10 +572,23 @@ mod tests {
567572
path: "/tmp/docs".to_string(),
568573
is_directory: true,
569574
size: None,
575+
recursive_size: None,
570576
modified: None,
571577
};
572578
let formatted = format_file_compact(&dir, 1, false, false, false);
573579
assert_eq!(formatted, "i:1 d docs");
580+
581+
// Directory with recursive size
582+
let dir_with_size = FileEntry {
583+
name: "src".to_string(),
584+
path: "/tmp/src".to_string(),
585+
is_directory: true,
586+
size: None,
587+
recursive_size: Some(169),
588+
modified: Some("2026-03-19T17:33:53.000Z".to_string()),
589+
};
590+
let formatted = format_file_compact(&dir_with_size, 5, false, false, true);
591+
assert_eq!(formatted, "i:5 d src 169B 2026-03-19T17:33:53.000Z");
574592
}
575593

576594
#[test]
@@ -585,13 +603,15 @@ mod tests {
585603
path: "/Users/test/file1.txt".to_string(),
586604
is_directory: false,
587605
size: Some(100),
606+
recursive_size: None,
588607
modified: Some("2024-01-15".to_string()),
589608
},
590609
FileEntry {
591610
name: "folder".to_string(),
592611
path: "/Users/test/folder".to_string(),
593612
is_directory: true,
594613
size: None,
614+
recursive_size: None,
595615
modified: None,
596616
},
597617
],

apps/desktop/src-tauri/src/mcp/tests.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ fn test_pane_state_store_update_left() {
536536
path: "/test/path/file1.txt".to_string(),
537537
is_directory: false,
538538
size: Some(1024),
539+
recursive_size: None,
539540
modified: Some("2024-01-01T00:00:00Z".to_string()),
540541
}],
541542
cursor_index: 0,
@@ -596,6 +597,7 @@ fn test_pane_state_cursor_index_bounds() {
596597
path: "/test/file1.txt".to_string(),
597598
is_directory: false,
598599
size: None,
600+
recursive_size: None,
599601
modified: None,
600602
}],
601603
cursor_index: 999, // Out of bounds
@@ -628,6 +630,7 @@ fn test_file_entry_serialization() {
628630
path: "/path/to/test.txt".to_string(),
629631
is_directory: false,
630632
size: Some(42),
633+
recursive_size: None,
631634
modified: Some("2024-01-01T00:00:00Z".to_string()),
632635
};
633636

@@ -644,6 +647,7 @@ fn test_file_entry_optional_fields_omitted() {
644647
path: "/path/dir".to_string(),
645648
is_directory: true,
646649
size: None,
650+
recursive_size: None,
647651
modified: None,
648652
};
649653

@@ -677,6 +681,7 @@ fn test_unicode_in_file_entries() {
677681
path: "/path/文件.txt".to_string(),
678682
is_directory: false,
679683
size: Some(100),
684+
recursive_size: None,
680685
modified: None,
681686
};
682687

@@ -693,20 +698,23 @@ fn test_special_chars_in_file_paths() {
693698
path: "/path/file with spaces.txt".to_string(),
694699
is_directory: false,
695700
size: None,
701+
recursive_size: None,
696702
modified: None,
697703
},
698704
FileEntry {
699705
name: "file'with'quotes.txt".to_string(),
700706
path: "/path/file'with'quotes.txt".to_string(),
701707
is_directory: false,
702708
size: None,
709+
recursive_size: None,
703710
modified: None,
704711
},
705712
FileEntry {
706713
name: "file\"doublequotes\".txt".to_string(),
707714
path: "/path/file\"doublequotes\".txt".to_string(),
708715
is_directory: false,
709716
size: None,
717+
recursive_size: None,
710718
modified: None,
711719
},
712720
];
@@ -750,6 +758,7 @@ fn test_large_file_count() {
750758
path: format!("/test/file{i:04}.txt"),
751759
is_directory: false,
752760
size: Some(i as u64 * 100),
761+
recursive_size: None,
753762
modified: None,
754763
})
755764
.collect();
@@ -867,6 +876,7 @@ fn test_null_bytes_in_paths() {
867876
path: "/path/file\x00hidden.txt".to_string(),
868877
is_directory: false,
869878
size: None,
879+
recursive_size: None,
870880
modified: None,
871881
};
872882

apps/desktop/src/lib/file-explorer/pane/FilePane.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@
587587
path: entry.path,
588588
isDirectory: entry.isDirectory,
589589
size: entry.size,
590+
recursiveSize: entry.recursiveSize,
590591
modified: entry.modifiedAt ? new Date(entry.modifiedAt * 1000).toISOString() : undefined,
591592
})
592593
}

apps/desktop/src/lib/tauri-commands/app-state.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface PaneFileEntry {
1212
path: string
1313
isDirectory: boolean
1414
size?: number
15+
recursiveSize?: number
1516
modified?: string
1617
}
1718

0 commit comments

Comments
 (0)