Files
rabby/docs/architecture.md
2026-07-06 11:23:36 +00:00

115 lines
5.4 KiB
Markdown

# Rabby Architecture
Rabby is a Rust/Tauri rewrite of Tabby. The architecture is designed to match Tabby's feature classes without rebuilding an Electron-shaped codebase in Rust.
## Goals
- Keep the desktop binary smaller than an Electron app where practical.
- Keep feature implementation honest and testable.
- Make local terminal, SSH, Telnet, Serial, transfer, settings, and plugin behavior independently replaceable.
- Keep the Tauri layer thin so future web or headless surfaces can reuse the same Rust services.
## Crate boundaries
| Layer | Responsibility | Must not contain |
| --- | --- | --- |
| `rabby-core` | Pure domain models: profiles, workspace, features, config, shortcuts, themes, terminal state, transfers. | Tauri, GTK/WebKit, OS keychain, network sockets, filesystem persistence. |
| `rabby-runtime` | Local runtime adapters: PTY, processes, notifications, config storage, platform paths, window control. | UI state or protocol-specific SSH/Telnet/Serial logic. |
| `rabby-protocols` | Remote/session protocol adapters: SSH, SFTP, Telnet, Serial, Zmodem detection. | Tauri commands or DOM/UI code. |
| `rabby-secrets` | Secret storage boundaries and OS keychain/encrypted-store implementations. | Plaintext logging, UI rendering, profile persistence. |
| `src-tauri` | Tauri command/event bridge and app bootstrap. | Business rules already expressible in core/runtime/protocol crates. |
| `ui` | Rendering and user interaction. | PTY, SSH, Telnet, Serial, keychain, or filesystem logic. |
## Adapter rule
Anything that touches the operating system, network, subprocesses, user keychains, windows, notifications, or filesystems must sit behind a trait boundary. Tests should use fake/in-memory adapters first, then optional integration tests for the real implementation.
Examples:
- `PtySession` for local shell sessions.
- `ConfigStore` for persisted settings and portable mode.
- `SecretStore` for keychain/encrypted secrets.
- `Notifier` for process completion notifications.
- `SshSession`, `SftpClient`, `TelnetSession`, and `SerialSession` for protocol behavior.
## Tauri thin-shell rule
Tauri commands should translate UI requests into typed service calls and emit typed events back to the UI. They should not parse terminal bytes, validate SSH forwarding rules, manage secret encryption, or implement profile business logic directly.
Good command shape:
```rust
#[tauri::command]
async fn terminal_open(profile_id: String, state: State<'_, AppServices>) -> Result<SessionId, CommandError> {
state.terminal_service.open(profile_id).await.map_err(CommandError::from)
}
```
Bad command shape:
```rust
#[tauri::command]
fn terminal_open(profile_id: String) {
// Parses config, opens SSH, stores password, mutates UI state, and writes files here.
}
```
## Testing pyramid
1. **Core unit tests:** fast tests for pure models and validation. These are required for every feature class.
2. **Adapter unit tests:** fake/in-memory implementations for runtime and protocol traits.
3. **Integration tests:** optional or feature-gated tests against real PTY, SSH, serial devices, keychains, and filesystems.
4. **Tauri command tests:** verify command serialization and service wiring with fake services.
5. **Linux smoke tests:** build release and launch under Xvfb to catch GUI startup regressions.
Every feature should move through this sequence before being marked `Implemented`.
## Feature status definitions
| Status | Meaning |
| --- | --- |
| `Planned` | The feature class is identified from Tabby and has an architectural placeholder, but no meaningful runtime behavior yet. |
| `UiPrototype` | The UI shows the feature or intended workflow, but runtime behavior is incomplete. |
| `Modeled` | Core domain state and validation exist, with unit tests, but full runtime integration is not complete. |
| `Implemented` | Core model, runtime/protocol behavior, Tauri command/UI path, and relevant tests/smoke checks exist. |
A feature must not be marked `Implemented` unless its tests prove real behavior beyond catalog presence.
## Feature implementation flow
1. Add or update the feature catalog entry in `rabby-core/src/feature/mod.rs`.
2. Write failing core tests for the domain model.
3. Implement the minimal core model.
4. Add runtime/protocol adapter traits and fake tests.
5. Add the real adapter implementation behind the trait.
6. Wire Tauri commands/events.
7. Update UI rendering/state.
8. Add smoke/integration coverage.
9. Generate/update feature parity documentation.
10. Only then change the feature status to `Implemented`.
## UI expandability
The static UI may remain while the feature set is small, but it must be split into pure state and rendering modules before adding substantial workflow logic. UI code should render typed state returned by Tauri commands; it should never duplicate profile validation, terminal parsing, or connection logic.
## Security rules
- Secrets are never stored in profile config as plaintext.
- `Debug`/log output for secret wrappers must redact values.
- Local file paths for downloads/uploads must be validated to prevent traversal mistakes.
- Plugin execution must not be added until manifest parsing and permission validation are implemented.
## Release quality gates
Before a major milestone or release:
```bash
cargo fmt --all -- --check
cargo test --workspace
cargo check --workspace
cargo build --release -p rabby
./scripts/smoke-linux.sh
```
The Linux smoke test should launch the GUI under Xvfb and treat a timeout with no panic as successful startup.