feat: Implement real-time streaming output with interactive multi-node UI
@inureyes is already working on this.
Since Oct 29, 2025.
Assessment
This issue has not been assessed yet.
Description
๐ 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โ 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 โ
// 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 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)
# 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 โ
- Implement
execute_streaming()API - Add
CommandOutputenum with StdOut/StdErr/ExitCode - Implement
CommandOutputBufferfor internal use - Ensure
execute()maintains backward compatibility (uses streaming internally) - Add error type for
JoinError - Add
execute_with_sudo()for sudo password handling
Task 2: Independent Stream Management โ
- Implement
NodeStreamstruct with independent buffering - Create
MultiNodeStreamManagerfor coordinating streams - Implement non-blocking polling (
poll()method) - Add per-node state management (ExecutionStatus)
- Handle partial failures gracefully
- Add
RollingBufferwith 10MB limit for memory protection
Task 3: Simple Output Modes โ
- Add
--streamflag for interleaved output with[node]prefixes - Implement
--output-dirfor per-node file output - Add TTY detection (auto-enable TUI in terminals)
- Update CLI argument parsing in
src/cli.rs - Implement
OutputModeenum (Normal/Stream/File/Tui)
Task 4: Interactive TUI โ
- Add
ratatuiandcrosstermdependencies - Implement summary view component
- Add detail view with node switching
- Implement split view mode (2-4 nodes)
- Add diff mode for comparing two nodes
- Implement progress parsing heuristics
- Add keyboard navigation
- Add auto-scroll control (follow mode)
- Implement help overlay (? key)
- Add terminal size validation with error message
Task 5: Testing & Documentation ๐ง
- Unit tests for stream management
- TUI integration tests with ratatui's test backend
- Update ARCHITECTURE.md with TUI architecture
- Add usage examples in README.md
๐ 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
RollingBufferwith 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
- Detection of
๐ฏ Remaining Work
-
Documentation
- Update ARCHITECTURE.md with new TUI module structure
- Add TUI screenshots to README
- Document keyboard shortcuts in help output
-
Testing
- Add TUI snapshot tests using ratatui's test backend
- Integration tests for streaming execution
- Performance tests for large output handling
-
Future Enhancements (Lower Priority)
- Configurable buffer sizes via CLI/config
- Output search/filtering within TUI
- Session recording and playback
- Per-node selective logging
๐ 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
- Original PR #37: https://github.com/lablup/bssh/pull/37
- russh documentation: https://docs.rs/russh/
- ratatui documentation: https://docs.rs/ratatui/
- ratatui examples: https://github.com/ratatui-org/ratatui/tree/main/examples
โ Acceptance Criteria (Status)
-
execute_streaming()API works with single node - Multi-node execution maintains independent streams per node
- Node switching is instant (no re-fetching of output)
- Each node preserves scroll position and state when switching
-
--streammode works in terminals and pipes - TUI activates automatically in interactive terminals
- All existing tests pass (backward compatibility)
- New tests cover streaming scenarios and view modes (partial)
- Documentation updated (README, ARCHITECTURE.md) (partial)
- Dominant language
- Rust
- Stars
- 65
- Forks
- 7
- Avg merge
- 1h 30m
- Merged PRs (30d)
- 25
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up โ it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from lablup/bssh
-
priority:medium status:backlog type:bug
Difficulty 5/5 Over a week Newbie friendliness 28/100
-
priority:high status:in-progress type:enhancement
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
priority:low status:backlog type:enhancement
-
priority:low status:backlog type:enhancement
-
priority:medium status:backlog type:enhancement
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ยท
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
bug team:backend track:services-maintenance
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
cowprotocol/services#4950 ยท
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 ยท 1 comment ยท