📋 Overview
Implement real-time command output streaming capability for SSH execution, inspired by PR #37 but with enhanced multi-node UI support. Currently, bssh waits for commands to complete before showing any output, making it difficult to monitor long-running operations across multiple nodes.
Note: This issue has been significantly updated to reflect the current implementation status as of v1.4.0. Most planned features have been implemented.
✅ Implementation Status Summary
| Feature |
Status |
Location |
| Core Streaming API |
✅ Complete |
src/ssh/tokio_client/channel_manager.rs |
| Independent Stream Management |
✅ Complete |
src/executor/stream_manager.rs |
| Simple Output Modes (--stream, --output-dir) |
✅ Complete |
src/cli.rs, src/executor/output_mode.rs |
| Interactive TUI (ratatui) |
✅ Complete |
src/ui/tui/ |
| Summary View |
✅ Complete |
src/ui/tui/views/summary.rs |
| Detail View |
✅ Complete |
src/ui/tui/views/detail.rs |
| Split View |
✅ Complete |
src/ui/tui/views/split.rs |
| Diff View |
✅ Complete |
src/ui/tui/views/diff.rs |
| Progress Parsing |
✅ Complete |
src/ui/tui/progress.rs |
| TTY Detection |
✅ Complete |
atty dependency |
| Memory Overflow Protection |
✅ Complete |
RollingBuffer with 10MB limit |
| Comprehensive Tests |
🚧 Partial |
Unit tests exist, more integration tests needed |
| Documentation |
🚧 Partial |
Code documented, ARCHITECTURE.md needs update |
🎯 Goals (Updated)
Real-time Output Streaming: Enable streaming of stdout/stderr as commands execute ✅ Complete
Multi-node Observability: Provide dynamic UI to monitor multiple nodes simultaneously ✅ Complete
Independent Stream Management: Maintain separate output streams per node ✅ Complete
Backward Compatibility: Maintain existing API and behavior ✅ Complete
🏗️ Architecture (Current Implementation)
Core Streaming Infrastructure ✅
// Implemented in src/ssh/tokio_client/channel_manager.rs
/// Command output variants for streaming
#[derive(Debug, Clone)]
pub enum CommandOutput {
StdOut(CryptoVec),
StdErr(CryptoVec),
ExitCode(u32),
}
impl Client {
// Existing method (backward compatible) - uses streaming internally
pub async fn execute(&self, cmd: &str) -> Result<CommandExecutedResult>;
// Streaming method
pub async fn execute_streaming(
&self,
command: &str,
sender: Sender<CommandOutput>
) -> Result<u32, Error>;
// Sudo password support
pub async fn execute_with_sudo(
&self,
command: &str,
sender: Sender<CommandOutput>,
sudo_password: &SudoPassword,
) -> Result<u32, Error>;
}
Independent Stream Management ✅
// Implemented in src/executor/stream_manager.rs
/// Independent output stream for a single node
pub struct NodeStream {
pub node: Node,
receiver: mpsc::Receiver<CommandOutput>,
stdout_buffer: RollingBuffer, // 10MB max with overflow protection
stderr_buffer: RollingBuffer,
status: ExecutionStatus,
exit_code: Option<u32>,
closed: bool,
}
/// Manager for coordinating multiple node streams
pub struct MultiNodeStreamManager {
streams: Vec<NodeStream>,
}
/// Execution status for a node's command
pub enum ExecutionStatus {
Pending,
Running,
Completed,
Failed(String),
}
TUI Architecture ✅
// Implemented in src/ui/tui/
pub mod app; // TuiApp, ViewMode
pub mod event; // Keyboard event handling
pub mod progress; // Progress bar parsing
pub mod terminal_guard; // RAII terminal cleanup
pub mod views; // summary, detail, split, diff
pub enum ViewMode {
Summary, // Show all nodes status
Detail(usize), // Focus on single node
Split(Vec<usize>), // Show multiple nodes in panes
Diff(usize, usize), // Compare two nodes side-by-side
}
📐 Multi-node UI (Implemented)
CLI Output Modes ✅
# TUI Mode (default when TTY detected)
$ bssh -C production "apt-get update"
# → Opens interactive TUI with real-time monitoring
# Stream Mode (--stream flag)
$ bssh -C prod --stream "command"
[node1] Starting process...
[node2] Starting process...
[node1] Progress: 50%
# File Mode (--output-dir flag)
$ bssh -C prod --output-dir ./logs "command"
# Creates: ./logs/node1_TIMESTAMP.stdout, etc.
# Normal Mode (auto when piped)
$ bssh -C prod "uptime" | grep -v idle
TUI Views (All Implemented) ✅
Summary View (Press Esc from other views)
┌──────────────────────────────────────────────────────────┐
│ Cluster: production - apt-get upgrade │
│ Total: 8 • ✓ 3 • ✗ 1 • 4 in progress │
├──────────────────────────────────────────────────────────┤
│ [1] node1 ✓ Completed (exit: 0) │
│ [2] node2 ⟳ [========= ] 75% │
│ [3] node3 ⟳ Running... │
│ [4] node4 ✗ Exit code: 1 │
│ [5] node5 ⟳ [== ] 25% │
├──────────────────────────────────────────────────────────┤
│ [1-9] Detail [s] Split [d] Diff [q] Quit [?] Help │
└──────────────────────────────────────────────────────────┘
Detail View (Press 1-9)
Full output view with scrolling and follow mode toggle (f key).
Split View (Press s)
Shows 2-4 nodes simultaneously in split panes.
Diff View (Press d)
Side-by-side comparison of two nodes.
Keyboard Controls ✅
1-9: Jump to node detail view
s: Enter split view
d: Enter diff view (select two nodes)
f: Toggle auto-scroll (follow mode)
↑/↓: Scroll output
←/→: Switch between nodes in detail view
Esc: Return to summary view
?: Show help overlay
q: Quit
📦 Dependencies (Current)
# Already implemented in Cargo.toml
ratatui = "0.29" # TUI framework
crossterm = "0.29" # Terminal control
atty = "0.2.14" # TTY detection
tokio = { version = "1.47.1", features = ["full"] }
indicatif = "0.18" # Progress indicators (parallel mode)
🛠️ Implementation Status
Task 1: Core Streaming API ✅
Task 2: Independent Stream Management ✅
Task 3: Simple Output Modes ✅
Task 4: Interactive TUI ✅
Task 5: Testing & Documentation 🚧
🎁 Additional Features Implemented (Beyond Original Scope)
The following features were implemented but not originally planned in this issue:
-
Sudo Password Support (execute_with_sudo())
- Automatic sudo prompt detection
- Secure password injection with PTY
- Multiple sudo prompt handling (up to 10 per session)
- Buffer size limits for security (64KB)
-
Memory Protection
RollingBuffer with configurable max size (10MB default)
- Automatic old data discard to prevent OOM
- Overflow logging and warnings
-
Terminal Guard
- RAII-based terminal cleanup
- Proper handling of crashes/panics
- Cursor visibility management
-
Progress Parsing Heuristics
- Detection of
XX% patterns
- Status message extraction from output
- Integration with summary view
🎯 Remaining Work
-
Documentation
-
Testing
-
Future Enhancements (Lower Priority)
📁 Current Project Structure (Relevant Files)
bssh/
├── src/
│ ├── cli.rs # CLI with --stream, --output-dir flags
│ ├── executor/
│ │ ├── mod.rs # ParallelExecutor exports
│ │ ├── output_mode.rs # OutputMode enum
│ │ └── stream_manager.rs # NodeStream, MultiNodeStreamManager
│ ├── ssh/
│ │ ├── client/
│ │ │ ├── mod.rs # SshClient exports
│ │ │ ├── command.rs # execute(), execute_streaming()
│ │ │ └── ...
│ │ └── tokio_client/
│ │ ├── mod.rs # Client, CommandOutput exports
│ │ ├── channel_manager.rs # CommandOutput, execute_streaming()
│ │ └── ...
│ ├── ui/
│ │ ├── mod.rs # UI exports
│ │ └── tui/
│ │ ├── mod.rs # run_tui(), TuiExitReason
│ │ ├── app.rs # TuiApp, ViewMode
│ │ ├── event.rs # Keyboard handling
│ │ ├── progress.rs # Progress parsing
│ │ ├── terminal_guard.rs # RAII terminal cleanup
│ │ └── views/
│ │ ├── mod.rs
│ │ ├── summary.rs
│ │ ├── detail.rs
│ │ ├── split.rs
│ │ └── diff.rs
│ └── commands/
│ └── exec.rs # Execute command with output modes
└── Cargo.toml # ratatui, crossterm, atty dependencies
📚 References
✅ Acceptance Criteria (Status)
📋 Overview
Implement real-time command output streaming capability for SSH execution, inspired by PR #37 but with enhanced multi-node UI support.
Currently, bssh waits for commands to complete before showing any output, making it difficult to monitor long-running operations across multiple nodes.✅ Implementation Status Summary
src/ssh/tokio_client/channel_manager.rssrc/executor/stream_manager.rssrc/cli.rs,src/executor/output_mode.rssrc/ui/tui/src/ui/tui/views/summary.rssrc/ui/tui/views/detail.rssrc/ui/tui/views/split.rssrc/ui/tui/views/diff.rssrc/ui/tui/progress.rsattydependencyRollingBufferwith 10MB limit🎯 Goals (Updated)
Real-time Output Streaming: Enable streaming of stdout/stderr as commands execute✅ CompleteMulti-node Observability: Provide dynamic UI to monitor multiple nodes simultaneously✅ CompleteIndependent Stream Management: Maintain separate output streams per node✅ CompleteBackward Compatibility: Maintain existing API and behavior✅ Complete🏗️ Architecture (Current Implementation)
Core Streaming Infrastructure ✅
Independent Stream Management ✅
TUI Architecture ✅
📐 Multi-node UI (Implemented)
CLI Output Modes ✅
TUI Views (All Implemented) ✅
Summary View (Press Esc from other views)
Detail View (Press 1-9)
Full output view with scrolling and follow mode toggle (f key).
Split View (Press s)
Shows 2-4 nodes simultaneously in split panes.
Diff View (Press d)
Side-by-side comparison of two nodes.
Keyboard Controls ✅
1-9: Jump to node detail views: Enter split viewd: Enter diff view (select two nodes)f: Toggle auto-scroll (follow mode)↑/↓: Scroll output←/→: Switch between nodes in detail viewEsc: Return to summary view?: Show help overlayq: Quit📦 Dependencies (Current)
🛠️ Implementation Status
Task 1: Core Streaming API ✅
execute_streaming()APICommandOutputenum with StdOut/StdErr/ExitCodeCommandOutputBufferfor internal useexecute()maintains backward compatibility (uses streaming internally)JoinErrorexecute_with_sudo()for sudo password handlingTask 2: Independent Stream Management ✅
NodeStreamstruct with independent bufferingMultiNodeStreamManagerfor coordinating streamspoll()method)RollingBufferwith 10MB limit for memory protectionTask 3: Simple Output Modes ✅
--streamflag for interleaved output with[node]prefixes--output-dirfor per-node file outputsrc/cli.rsOutputModeenum (Normal/Stream/File/Tui)Task 4: Interactive TUI ✅
ratatuiandcrosstermdependenciesTask 5: Testing & Documentation 🚧
🎁 Additional Features Implemented (Beyond Original Scope)
The following features were implemented but not originally planned in this issue:
Sudo Password Support (
execute_with_sudo())Memory Protection
RollingBufferwith configurable max size (10MB default)Terminal Guard
Progress Parsing Heuristics
XX%patterns🎯 Remaining Work
Documentation
Testing
Future Enhancements (Lower Priority)
📁 Current Project Structure (Relevant Files)
📚 References
✅ Acceptance Criteria (Status)
execute_streaming()API works with single node--streammode works in terminals and pipes