fix(app): address code audit findings — app module#68
Conversation
leszek3737
commented
Jun 4, 2026
- Fix wrong MIME types: Julia .jl → text/x-julia, bat/cmd → text/x-msdos-batch, .mm → text/x-objective-c++
- Fix case-sensitive FS mismatch in CONFIG_EXACT_NAMES (exact match on Linux, case-insensitive on macOS/Windows)
- Fix thread leak in JobRunner Drop (single reaper thread, 5s deadline)
- Fix shell error merging (log raw_err, return PermissionDenied over NotFound)
- Fix FileEntryBuilder accepting empty names
- Fix FileSize rounding edge case (while-loop for cascading promotion)
- Cache canonical path per watcher poll, dedup events per path
- Cache grapheme_count in TextInput (O(n) → O(1) cursor ops)
- Box large DialogKind variants (240B → 24B stack size)
- Bound channel in job_runner (sync_channel(128))
- Add panel history limit (256 entries)
- Add hotlist validation (filter empty/whitespace paths)
- Add BufWriter in debug_log, single stderr lock
- Add OnceLock cache for get_shell
- Add #[must_use] on paths.rs public functions
- Add SortMode methods and Hash derive
- Extract helpers in user_menu (non_utf8_err, collect_body_lines)
- Split poll_watcher_events into drain/accumulate/apply
- Improve tests: panel_with_n helper, WatcherHarness, let/else patterns, remove duplicates
- Fix wrong MIME types: Julia .jl → text/x-julia, bat/cmd → text/x-msdos-batch, .mm → text/x-objective-c++ - Fix case-sensitive FS mismatch in CONFIG_EXACT_NAMES (exact match on Linux, case-insensitive on macOS/Windows) - Fix thread leak in JobRunner Drop (single reaper thread, 5s deadline) - Fix shell error merging (log raw_err, return PermissionDenied over NotFound) - Fix FileEntryBuilder accepting empty names - Fix FileSize rounding edge case (while-loop for cascading promotion) - Cache canonical path per watcher poll, dedup events per path - Cache grapheme_count in TextInput (O(n) → O(1) cursor ops) - Box large DialogKind variants (240B → 24B stack size) - Bound channel in job_runner (sync_channel(128)) - Add panel history limit (256 entries) - Add hotlist validation (filter empty/whitespace paths) - Add BufWriter in debug_log, single stderr lock - Add OnceLock cache for get_shell - Add #[must_use] on paths.rs public functions - Add SortMode methods and Hash derive - Extract helpers in user_menu (non_utf8_err, collect_body_lines) - Split poll_watcher_events into drain/accumulate/apply - Improve tests: panel_with_n helper, WatcherHarness, let/else patterns, remove duplicates
There was a problem hiding this comment.
Sorry @leszek3737, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
There was a problem hiding this comment.
Code Review
This pull request introduces various performance optimizations, refactorings, and bug fixes across the codebase, notably caching grapheme counts in TextInput, boxing large DialogKind variants to reduce stack size, caching shell paths, and batching file watcher events to reduce UI thread overhead. Feedback focuses on addressing a potential panic in ends_with_ignore_ascii_case when slicing non-char boundaries, ensuring BufWriter flushes on every write to prevent lost debug logs, removing a premature atomic optimization in directory creation, and eliminating redundant blocking disk I/O and system calls in directory tree traversal and watcher event processing.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Greptile SummaryThis PR addresses a broad code audit across the
Confidence Score: 4/5Safe to merge with the watcher rename-event fix applied; all other changes are well-scoped and follow existing patterns. The watcher refactor is the highest-risk area. The src/app/watcher_sync.rs — the Renamed event accumulation logic around lines 177–186 Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[poll_watcher_events] --> B[drain_events\nup to 256 from channel]
B --> C{events empty?}
C -- yes --> D[return false]
C -- no --> E[PanelCache::from_panel\nleft + right]
E --> F[accumulate_changes\nloop over events]
F --> G{event type}
G -- Created/Modified --> H[event_is_panel_dir_cached\nleft? right?]
G -- Deleted --> I[event_is_panel_dir_cached\nleft? right?]
G -- Renamed from/to --> J[Check 'from' left/right\nCheck 'to' left/right ⚠️ OR-bug]
G -- Overflow --> K[overflow = true]
H --> L[AccumulatedChanges]
I --> L
J --> L
K --> L
L --> M[apply_panel_changes]
M --> N[apply_dir_event left]
M --> O[apply_dir_event right]
M --> P{needs_full_refresh?}
P -- yes --> Q[full_refresh_panels\nread_directory IO]
P -- no --> R[apply_file_events\nper-path upsert/remove]
Q --> S[rebuild_visible_entries]
R --> S
S --> T[return dirty]
Reviews (1): Last reviewed commit: "fix(app): address code audit findings — ..." | Re-trigger Greptile |
- Replace byte-slicing with char-iter in ends_with_ignore_ascii_case - Flush debug_log after every write to prevent log loss on crash - Remove DIR_CREATED premature AtomicBool optimization - Remove canonicalize() calls from event_is_panel_dir_cached - Use entry.file_type() cached from read_dir instead of symlink_metadata - Fix rename event touching wrong panel (|| → independent ifs)
WS-A notify watcher: - pair renames by cookie/path instead of FIFO pop_front - platform-correct unwatch error handling (ENOENT/EINVAL vs ERROR_NOT_FOUND) - rebuild guarded state on mutex poison instead of continuing on partial state - bound pending_from queue with overflow handling - reduce per-event PathBuf clones and lock cycles in the hot path WS-B directory tree: - push entries with read_error on metadata failure and on detected cycles (regression #68: entries no longer silently dropped) - return Option from file_key; skip cycle detection when identifiers are unavailable (avoids Windows (0,0) key collision) - size children Vec from a single dir read WS-C watcher sync: - dedup cached apply/remove and watcher upsert/remove via generics - compute clean_path once per event in path_matches_any - lazy allocation in drain_events WS-D path/reader/cha/mod: - strip leading separators cross-platform (Windows backslash absolute-path bug) - Cow-based env expansion, std::env::var fast path - os_str_to_arc without unwrap; dedup filename conversion - UID_CACHE poison dump+rebuild+clear_poison - unify Cha is_* via ChaMode; document time-API access; PermBits table - fs re-exports (FileEntry, Cha, WatchEvent); fix sequential-read doc Tests: rename-pairing interleave, pending_from overflow, dir-tree read_error + cycle + descent-skip, deterministic cooldown.