Add Connectivity feature: remote file browsing, sessions, CI extraction, themes#10
Merged
bluestreak01 merged 9 commits intomasterfrom Apr 15, 2026
Merged
Conversation
…, NFS
Adds a comprehensive remote file browsing system to middle-manager,
branded as "Connectivity [experimental]". Users can browse, edit, copy,
and manage files across 8 remote protocols directly from the dual-panel
file manager.
## Remote Protocols (Ctrl+T)
All protocols implement a common `RemoteFs` trait, so adding new
protocols requires zero changes to dispatch code.
- **SSH**: Terminal sessions via system `ssh`, with auto-reconnect on disconnect
- **SFTP**: File browsing via `sftp` CLI in batch mode
- **SMB**: File browsing via `smbclient` CLI
- **WebDAV**: File browsing via `curl` + `quick-xml` PROPFIND parsing
- **S3**: Object storage via `aws s3api` (JSON output, supports S3-compatible
like MinIO, Backblaze B2, Cloudflare R2 via --endpoint-url)
- **GCS**: Google Cloud Storage via `gcloud storage` (JSON format)
- **Azure Blob**: Via `az storage blob` with connection string support,
container browsing, and automatic API version backoff for Azurite
- **NFS**: Mount-based with automatic unmount on disconnect
## Session Persistence (--session / Ctrl+Y)
- `middle-manager --session <name>` creates/attaches to tmux sessions
- Sessions survive terminal disconnects; reattach from any device via SSH
- Tmux prefix set to backtick to avoid hotkey conflicts
- Nested session detection prevents accidental tmux-in-tmux
- Session manager dialog (Ctrl+Y) for create/attach/kill
## CI Failure Extraction (Ctrl+E)
- Extracts failed test names from Azure DevOps and GitHub Actions CI logs
- Azure test results API (fast path) with PAT auth support
- Falls back to log tail download (last 512KB) with gzip compression
- Parses Rust, Java/Maven/Gradle, Go, Python, Jest failure patterns
- Writes consolidated Markdown report grouped by check
- GitHub API rate limit monitoring
- Real-time progress in status bar
## Theme System (Shift+F1)
- Settings dialog with theme cycling (Left/Right arrows)
- QuestDB Dark theme: deep purple-black backgrounds, rose-pink accents
using QuestDB brand colors (#d14671, #892c6c)
- Theme persisted in state.json, loaded on startup
- Thread-local cache with generation counter avoids RwLock on every frame
## Saved Connections
- F2 in remote dialog saves current connection to connections.json
- Saved connections shown on dialog open for quick reconnect
- Delete saved connections with Del key
## Other Enhancements
- **Touch/create file** (Shift+F7) for local and remote panels
- **Remote file editing**: F3/F4 downloads to temp, edits, uploads on save
- **Error popups**: Red-bordered for errors, green for success, dismissible
- **Status bar**: Shows progress messages with 5-second auto-clear
- **Debug logging**: MM_DEBUG=1 logs all shell commands to debug.log
- **Linux clipboard**: Native xclip/xsel/wl-copy support (falls back to OSC 52)
- **Empty file editor fix**: No more panic on 0-byte files
## New Hotkeys
| Key | Context | Action |
|-----|---------|--------|
| Ctrl+T | File panel | Open remote connection dialog |
| Ctrl+T | Remote panel | Disconnect and return to local |
| Ctrl+Y | File panel | Open session manager |
| Ctrl+E | CI panel | Extract all test failures |
| Shift+F1 | File panel | Open settings |
| Shift+F7 | File panel | Create (touch) new file |
| F2 | Remote dialog | Save connection |
| Alt+Left/Right | Remote dialog | Cycle protocol |
| Tab | Remote dialog | Cycle fields / switch mode |
| Del | Saved connections | Remove saved connection |
## Architecture
- `RemoteFs` trait in `src/remote_fs.rs` — common interface for all protocols
- `PanelSource::Remote { Rc<dyn RemoteFs> }` — single enum variant for all remotes
- Background thread connections via `spawn_remote_connect()` + mpsc polling
- 30-second connection timeout with progress display
- All protocols shell out to CLI tools (no native library dependencies except quick-xml)
## Testing
- 408 unit tests (331 binary + 67 lib + 10 integration)
- Integration tests for S3 (S3Mock), Azure (Azurite), SFTP (localhost)
- Multiple security/performance audit passes
- Bounds-checked array access, no panics on user input
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13a5faa to
2bf4d97
Compare
- Fix tmux intercepting mouse scroll: unbind WheelUpPane/WheelDownPane from copy-mode, rebind with send-keys -M to pass through to app - Add Shift+PageUp/PageDown for keyboard scrolling in Claude panel (20 lines at a time, since regular PageUp/Down are forwarded to Claude) - Mouse scroll in Claude panel scrolls 3 lines at a time Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bluestreak01
added a commit
that referenced
this pull request
Apr 4, 2026
Adds two major features for PR code review: **PR Diff Panel (Ctrl+D)** - Tree view of files changed in the current PR - Grouped by directory with expand/collapse - File status indicators (Added/Modified/Deleted/Renamed) - Quick search: type to filter, Up/Down to cycle matches - Persisted across sessions **Side-by-Side Diff Viewer** - Full-file diff with base branch (via git merge-base) - Syntax highlighting on both panels - Text selection (Shift+arrows) and clipboard copy (Ctrl+C) - Search with match highlighting (Ctrl+F, n/N) - Hunk navigation (Alt+Up/Down) skips to next/prev diff hunk - Terminal caret on either panel, Tab to switch sides - F4 toggles to editor at current line (Esc returns) - Viewport position preserved across editor/viewer transitions **Architecture improvements** - Replaced 5 separate focus fields with single PanelFocus enum - Extracted focused_side() helper for bottom panel resize logic - Bottom panel key/action intercepts guarded by mode check - 346 tests (33 new covering tree building, diff parsing, navigation, selection, search, and rendering helpers) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bluestreak01
added a commit
that referenced
this pull request
Apr 4, 2026
…y-and-enhancements # Conflicts: # src/action.rs # src/app.rs # src/main.rs # src/ui/footer.rs # src/ui/mod.rs
Critical (crashes/security): - Fix RwLock deadlock in theme() when THEME is None - Fix SFTP command injection via newlines in shell_quote() - Fix SMB command injection via semicolons in to_smb_path() - Fix WebDAV credentials visible in process table (use curl stdin config) - Remove default TLS verification bypass in WebDAV (opt-in insecure flag) - Pass Azure SAS tokens/connection strings via env vars, not CLI args - Set 0600 permissions on saved connections file - Fix byte-boundary string slicing panics with char-aware truncation - Fix NFS path traversal via .. components High (data loss/logic bugs): - Snapshot active_panel at copy dialog open to prevent panel swap bug - Azure rename: only delete source after confirmed successful copy - Azure rename: use dst_container for cross-container moves - move_entry: only fallback to copy+delete on EXDEV, not all errors - copy_dir_recursive: handle symlinks to prevent infinite recursion - Remove redundant double-poll of dir_watcher.has_changes() - Settings dialog: Left key now cycles theme backward - Tmux bind-key: target specific session instead of global - CI Azure test results: continue on bad run IDs instead of aborting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Security-critical escaping: - sftp shell_quote: control chars, newlines, quotes, backslashes (10 tests) - smb to_smb_path: semicolons, quotes, backslashes, combined (7 tests) UTF-8 safety: - truncate_to_width: ASCII, CJK, emoji, multi-byte, edge cases (8 tests) - ceil_char_boundary: mid-char, boundaries, past-end (6 tests) Path traversal / filesystem: - NFS normalize_path + local_path traversal guard (10 tests) - fs_ops move_entry EXDEV handling, error propagation (3 tests) - fs_ops copy_dir_recursive with symlinks and loops (3 tests) Azure / CI: - azure_blob resolve_path, to_prefix, connection string parsing (15 tests) - ci.rs parse_failures across 6 CI frameworks + edge cases (17 tests) Saved connections: - Serde round-trip, file permissions 0600/0700, load/save (14 tests) WebDAV: - insecure flag, URL construction, display labels (7 tests) Theme: - next()/prev() cycling and round-trip (5 tests) Integration tests: - Fix no-op WebDAV/SMB parser tests to call actual parsers - Panic on connect failure after skip-guard passes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Member
|
Member
|
i would suggest the following:
and lets not bother with test name extraction |
…ialog, settings - Add Shift+F2 as alternative to Ctrl+T for connectivity (Mac compat) - Show blocking popup with summary after CI failure extraction - Replace log downloads with API-only extraction (GitHub annotations, Azure test results) - Require and validate PAT/auth before starting extraction - Add spacebar to cycle theme in settings dialog for consistency - Fix connectivity dialog tab ordering: Tab/BackTab cycle fields uniformly - Extract failure info (error messages) alongside test names Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…y-and-enhancements Resolve conflicts between remote connectivity features (SSH/SFTP/S3/etc) and master's new features (copy options, dir size calc, clipboard module, hex editor, sparse copy, overwrite dialog). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…y-and-enhancements
Bugs fixed: - Settings dialog now uses shared dialog_helpers (render_dialog_frame, dialog_styles) instead of ad-hoc rendering - Popup colors use theme (popup_error_border, popup_success_border) instead of hardcoded Color::Red/Green - SSH dialog BackTab now cycles fields backward (new ToggleReverse action) - NFS copy_dir_recursive skips symlinks to prevent infinite recursion - Remove dead code: sftp remove_file(), debug_log log_cmd() - ThemeName::all() changed from #[allow(dead_code)] to #[cfg(test)] Duplication eliminated: - Default download_dir/upload_dir implementations on RemoteFs trait (removed identical copies from sftp, smb, webdav) - Shared path_to_prefix() in remote_fs.rs (was duplicated in s3, gcs, azure) - Shared format_size() in remote_fs.rs (was duplicated in ci, hex_view, parquet) - Shared config_dir() in remote_fs.rs (was duplicated in 4 files) - Deleted render_smb/render_webdav (use generic render_fields) - Extracted render_input_bar/render_dropdown_list in panel_view.rs - Extracted footer_styles() and build_colon_spans() in footer.rs Allocation improvements: - SSH host list: single buffer + display_label() called once per host - Footer: split ": label" into two Spans (zero format! per key) - Popup: replaced title.to_lowercase() with direct contains checks - SSH filter: pre-computed lowercase search strings (hosts_lower) Clippy fixes: - All clippy warnings resolved (range contains, redundant closure, collapsible if, complex type alias, thread_local const, etc.) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bluestreak01
approved these changes
Apr 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a comprehensive Connectivity feature (experimental) to middle-manager, enabling remote file browsing across 8 protocols, persistent tmux sessions, CI test failure extraction, and a theme system.
Remote File Browsing (
Ctrl+T)RemoteFstrait — adding new protocols requires zero dispatch code changesssh,sftp,smbclient,curl,aws,gcloud,az,mount) for maximum compatibilityAlt+Left/Rightto cycle)F2to save, stored in~/.config/middle-manager/connections.json)Session Persistence (
--session/Ctrl+Y)middle-manager --session <name>creates/attaches to persistent tmux sessionsCtrl+Y) for create/attach/killCI Failure Extraction (
Ctrl+E)Theme System (
Shift+F1)Other
Shift+F7) on local and remote panelsMM_DEBUG=1)New Hotkeys
Ctrl+TCtrl+YCtrl+EShift+F1Shift+F7F2Alt+←/→Architecture
RemoteFstrait (src/remote_fs.rs) — 10 methods, implemented by all 7 remote connection typesPanelSource::Remote { Rc<dyn RemoteFs> }— single enum variant replaces per-protocol variantsspawn_remote_connect()+ mpsc channel pollingquick-xmlfor WebDAV XML parsing)Test plan
Ctrl+T→ each protocol tab → connect → browse → copy files--session foo→ detach → reattachCtrl+Eon a PR with CI failuresShift+F1→ switch theme → verify persistence🤖 Generated with Claude Code