docs: update docs for multi-machine implementation (Phases A-D)
Update phases.md with completed multi-machine phases A-D. Add session entry to progress.md. Update task_plan.md decisions log and open questions. Update multi-machine.md status to implemented. Update CLAUDE.md files with new paths and deps. Add multi-machine section to README.md. Mark multi-machine as done in TODO.md with new follow-up items. Add changelog entries for all multi-machine components.
This commit is contained in:
parent
5503340e87
commit
0a17c09a46
8 changed files with 184 additions and 40 deletions
|
|
@ -1,4 +1,6 @@
|
|||
# Multi-Machine Support — Architecture Design
|
||||
# Multi-Machine Support — Architecture & Implementation
|
||||
|
||||
**Status: Implemented (Phases A-D complete, 2026-03-06)**
|
||||
|
||||
## Overview
|
||||
|
||||
|
|
@ -240,38 +242,45 @@ New "Machines" section in settings:
|
|||
|
||||
Stored in SQLite `settings` table as JSON: `remote_machines` key.
|
||||
|
||||
## Implementation Plan
|
||||
## Implementation (All Phases Complete)
|
||||
|
||||
### Phase A: Extract `bterminal-core` crate
|
||||
### Phase A: Extract `bterminal-core` crate [DONE]
|
||||
|
||||
- Extract `PtyManager` and `SidecarManager` into a shared crate
|
||||
- `src-tauri` depends on `bterminal-core` instead of owning the code
|
||||
- Zero behavior change — purely structural refactor
|
||||
- **Estimate:** ~2h of mechanical refactoring
|
||||
- Cargo workspace at v2/ level (v2/Cargo.toml with members: src-tauri, bterminal-core, bterminal-relay)
|
||||
- PtyManager and SidecarManager extracted to v2/bterminal-core/
|
||||
- EventSink trait (bterminal-core/src/event.rs) abstracts event emission
|
||||
- TauriEventSink (src-tauri/src/event_sink.rs) implements EventSink for AppHandle
|
||||
- src-tauri pty.rs and sidecar.rs are thin re-export wrappers
|
||||
|
||||
### Phase B: Build `bterminal-relay` binary
|
||||
### Phase B: Build `bterminal-relay` binary [DONE]
|
||||
|
||||
- WebSocket server using `tokio-tungstenite`
|
||||
- Token auth on upgrade
|
||||
- Routes commands to `bterminal-core` managers
|
||||
- Forwards events back over WebSocket
|
||||
- Includes `--port`, `--token`, `--insecure` CLI flags
|
||||
- **Ships as:** single static Rust binary (~5MB), `cargo install bterminal-relay`
|
||||
- v2/bterminal-relay/src/main.rs — WebSocket server (tokio-tungstenite)
|
||||
- Token auth on WebSocket upgrade (Authorization: Bearer header)
|
||||
- CLI: --port (default 9750), --token (required), --insecure (allow ws://)
|
||||
- Routes RelayCommand to bterminal-core managers, forwards RelayEvent over WebSocket
|
||||
- Rate limiting: 10 failed auth attempts triggers 5-minute lockout
|
||||
- Per-connection isolated PtyManager + SidecarManager instances
|
||||
|
||||
### Phase C: Add `RemoteManager` to controller
|
||||
### Phase C: Add `RemoteManager` to controller [DONE]
|
||||
|
||||
- New `remote.rs` module in `src-tauri`
|
||||
- Manages WebSocket client connections
|
||||
- Tauri commands: `remote_add`, `remote_remove`, `remote_connect`, `remote_disconnect`
|
||||
- Forwards remote events as Tauri events (same `sidecar-message` / `pty-data` events, tagged with machine ID)
|
||||
- v2/src-tauri/src/remote.rs — RemoteManager struct with WebSocket client connections
|
||||
- 12 Tauri commands: remote_add_machine, remote_remove_machine, remote_connect, remote_disconnect, remote_list_machines, remote_pty_spawn/write/resize/kill, remote_agent_query/stop, remote_sidecar_restart
|
||||
- Heartbeat ping every 15s
|
||||
|
||||
### Phase D: Frontend integration
|
||||
### Phase D: Frontend integration [DONE]
|
||||
|
||||
- Extend bridge adapters with `remoteMachineId` routing
|
||||
- Add machine management UI in settings
|
||||
- Add machine status indicators in sidebar
|
||||
- Add reconnection banner in pane chrome
|
||||
- Test with 2 machines (local + 1 remote)
|
||||
- v2/src/lib/adapters/remote-bridge.ts — machine management IPC adapter
|
||||
- v2/src/lib/stores/machines.svelte.ts — remote machine state store
|
||||
- Pane.remoteMachineId field in layout store
|
||||
- agent-bridge.ts and pty-bridge.ts route to remote commands when remoteMachineId is set
|
||||
- SettingsDialog "Remote Machines" section
|
||||
- Sidebar auto-groups remote panes by machine label
|
||||
|
||||
### Remaining Work
|
||||
|
||||
- [ ] Reconnection logic with exponential backoff (1s-30s cap)
|
||||
- [ ] Real-world relay testing (2 machines)
|
||||
- [ ] TLS/certificate pinning
|
||||
|
||||
## Security Considerations
|
||||
|
||||
|
|
|
|||
|
|
@ -254,12 +254,39 @@ bterminal-v2/
|
|||
|
||||
---
|
||||
|
||||
## Future: Multi-Machine Support [status: designed]
|
||||
## Multi-Machine Support (Phases A-D) [status: complete]
|
||||
|
||||
Architecture designed in [multi-machine.md](multi-machine.md). Extends BTerminal to manage agents and terminals on remote machines over WebSocket.
|
||||
Architecture designed in [multi-machine.md](multi-machine.md). Implementation extends BTerminal to manage agents and terminals on remote machines over WebSocket.
|
||||
|
||||
### Implementation Phases (A-D)
|
||||
- [ ] **Phase A:** Extract `bterminal-core` crate (PtyManager + SidecarManager shared code)
|
||||
- [ ] **Phase B:** Build `bterminal-relay` binary (WebSocket server, token auth, CLI flags)
|
||||
- [ ] **Phase C:** Add `RemoteManager` to controller (remote.rs, WebSocket client connections)
|
||||
- [ ] **Phase D:** Frontend integration (bridge adapters with remoteMachineId routing, machine management UI)
|
||||
### Phase A: Extract `bterminal-core` crate [status: complete]
|
||||
- [x] Created Cargo workspace at v2/ level (v2/Cargo.toml with members)
|
||||
- [x] Extracted PtyManager and SidecarManager into shared `bterminal-core` crate
|
||||
- [x] Created EventSink trait to abstract Tauri event emission (bterminal-core/src/event.rs)
|
||||
- [x] TauriEventSink in src-tauri/src/event_sink.rs implements EventSink
|
||||
- [x] src-tauri pty.rs and sidecar.rs now thin re-exports from bterminal-core
|
||||
|
||||
### Phase B: Build `bterminal-relay` binary [status: complete]
|
||||
- [x] WebSocket server using tokio-tungstenite with token auth
|
||||
- [x] CLI flags: --port, --token, --insecure (clap)
|
||||
- [x] Routes RelayCommand to PtyManager/SidecarManager, forwards RelayEvent over WebSocket
|
||||
- [x] Rate limiting on auth failures (10 attempts, 5min lockout)
|
||||
- [x] Per-connection isolated PTY + sidecar managers
|
||||
|
||||
### Phase C: Add `RemoteManager` to controller [status: complete]
|
||||
- [x] New remote.rs module in src-tauri — WebSocket client connections to relay instances
|
||||
- [x] Machine lifecycle: add/remove/connect/disconnect
|
||||
- [x] 12 new Tauri commands for remote operations
|
||||
- [x] Heartbeat ping every 15s
|
||||
|
||||
### Phase D: Frontend integration [status: complete]
|
||||
- [x] remote-bridge.ts adapter for machine management + remote events
|
||||
- [x] machines.svelte.ts store for remote machine state
|
||||
- [x] Layout store: Pane.remoteMachineId field
|
||||
- [x] agent-bridge.ts and pty-bridge.ts route to remote commands when remoteMachineId is set
|
||||
- [x] SettingsDialog "Remote Machines" section (add/remove/connect/disconnect)
|
||||
- [x] Sidebar auto-groups remote panes by machine label
|
||||
|
||||
### Remaining Work
|
||||
- [ ] Reconnection logic with exponential backoff
|
||||
- [ ] Real-world relay testing (2 machines)
|
||||
- [ ] TLS/certificate pinning
|
||||
|
|
|
|||
|
|
@ -264,8 +264,57 @@ Design: No separate sidecar process per subagent. Parent's sidecar handles all;
|
|||
- [x] 4-phase implementation plan: A (extract bterminal-core crate), B (relay binary), C (RemoteManager), D (frontend)
|
||||
- [x] Updated TODO.md and docs/task_plan.md to reference the design
|
||||
|
||||
### Session: 2026-03-06 (continued) — Multi-Machine Implementation (Phases A-D)
|
||||
|
||||
#### Phase A: bterminal-core crate extraction
|
||||
- [x] Created Cargo workspace at v2/ level (v2/Cargo.toml, workspace members: src-tauri, bterminal-core, bterminal-relay)
|
||||
- [x] Extracted PtyManager into v2/bterminal-core/src/pty.rs
|
||||
- [x] Extracted SidecarManager into v2/bterminal-core/src/sidecar.rs
|
||||
- [x] Created EventSink trait (v2/bterminal-core/src/event.rs) to abstract event emission
|
||||
- [x] TauriEventSink (v2/src-tauri/src/event_sink.rs) implements EventSink for Tauri AppHandle
|
||||
- [x] src-tauri/src/pty.rs and sidecar.rs now thin re-export wrappers
|
||||
- [x] Cargo.lock moved from src-tauri/ to workspace root (v2/)
|
||||
|
||||
#### Phase B: bterminal-relay binary
|
||||
- [x] New Rust binary at v2/bterminal-relay/ with WebSocket server (tokio-tungstenite)
|
||||
- [x] Token auth via Authorization: Bearer header on WebSocket upgrade
|
||||
- [x] CLI flags: --port (default 9750), --token (required), --insecure (allow ws://)
|
||||
- [x] Routes RelayCommand types (pty_create/write/resize/close, agent_query/stop, sidecar_restart, ping)
|
||||
- [x] Forwards RelayEvent types (pty_data/exit, sidecar_message/exited, error, pong, ready)
|
||||
- [x] Rate limiting: 10 failed auth attempts triggers 5-minute lockout
|
||||
- [x] Per-connection isolated PtyManager + SidecarManager instances
|
||||
|
||||
#### Phase C: RemoteManager in controller
|
||||
- [x] New v2/src-tauri/src/remote.rs module — RemoteManager struct
|
||||
- [x] WebSocket client connections to relay instances (tokio-tungstenite)
|
||||
- [x] RemoteMachine struct: id, label, url, token, status (Connected/Connecting/Disconnected/Error)
|
||||
- [x] Machine lifecycle: add_machine, remove_machine, connect, disconnect
|
||||
- [x] 12 new Tauri commands: remote_add_machine, remote_remove_machine, remote_connect, remote_disconnect, remote_list_machines, remote_pty_spawn/write/resize/kill, remote_agent_query/stop, remote_sidecar_restart
|
||||
- [x] Heartbeat ping every 15s to detect stale connections
|
||||
|
||||
#### Phase D: Frontend integration
|
||||
- [x] v2/src/lib/adapters/remote-bridge.ts — IPC adapter for machine management + remote events
|
||||
- [x] v2/src/lib/stores/machines.svelte.ts — Svelte 5 store for remote machine state
|
||||
- [x] Layout store: added remoteMachineId?: string to Pane interface
|
||||
- [x] agent-bridge.ts: routes to remote_agent_query/stop when pane has remoteMachineId
|
||||
- [x] pty-bridge.ts: routes to remote_pty_spawn/write/resize/kill when pane has remoteMachineId
|
||||
- [x] SettingsDialog: new "Remote Machines" section (add/remove/connect/disconnect UI)
|
||||
- [x] SessionList sidebar: auto-groups remote panes by machine label
|
||||
|
||||
#### Verification
|
||||
- cargo check --workspace: clean (0 errors)
|
||||
- vitest: 114/114 tests passing
|
||||
- svelte-check: clean (0 errors)
|
||||
|
||||
#### New dependencies added
|
||||
- bterminal-core: serde, serde_json, log, portable-pty, uuid (extracted from src-tauri)
|
||||
- bterminal-relay: tokio, tokio-tungstenite, clap, env_logger, futures-util
|
||||
- src-tauri: tokio-tungstenite, tokio, futures-util, uuid (added for RemoteManager)
|
||||
|
||||
### Next Steps
|
||||
- [ ] Reconnection logic with exponential backoff
|
||||
- [ ] Real-world relay testing (2 machines)
|
||||
- [ ] TLS/certificate pinning for relay connections
|
||||
- [ ] Deno sidecar: test with real claude CLI, benchmark startup time vs Node.js
|
||||
- [ ] E2E testing with Playwright/WebDriver (when display server available)
|
||||
- [ ] Multi-machine Phase A: extract bterminal-core crate
|
||||
- [ ] Test agent teams with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
## Goal
|
||||
Redesign BTerminal from a GTK3 terminal emulator into a **multi-session Claude agent dashboard** optimized for 32:9 ultrawide (5120x1440). Simultaneous visibility of all active sessions, agent tree visualization, inline markdown rendering, maximum information density.
|
||||
|
||||
## Status: Phases 1-7 Complete — Rev 4
|
||||
## Status: Phases 1-7 + Multi-Machine (A-D) Complete — Rev 5
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -103,10 +103,11 @@ When SDK changes its message format, only the adapter needs updating.
|
|||
|
||||
## Implementation Phases
|
||||
|
||||
See [phases.md](phases.md) for the full phased implementation plan (Phases 1-6).
|
||||
See [phases.md](phases.md) for the full phased implementation plan.
|
||||
|
||||
- **MVP:** Phases 1-4 (scaffolding, terminal+layout, agent SDK, session mgmt+markdown)
|
||||
- **Post-MVP:** Phases 5-7 (agent tree, polish, packaging, agent teams)
|
||||
- **Multi-Machine:** Phases A-D (bterminal-core extraction, relay binary, RemoteManager, frontend)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -141,11 +142,16 @@ See [phases.md](phases.md) for the full phased implementation plan (Phases 1-6).
|
|||
| Auto-update signing key | Generated minisign keypair. Pubkey set in tauri.conf.json. Private key for TAURI_SIGNING_PRIVATE_KEY GitHub secret. | 2026-03-06 |
|
||||
| Agent teams: frontend routing only | Subagent panes created by frontend dispatcher, not separate sidecar processes. Parent sidecar handles all messages; routing uses SDK's parentId field. Avoids process explosion for nested subagents. | 2026-03-06 |
|
||||
| SUBAGENT_TOOL_NAMES detection | Detect subagent spawn by tool_call name ('Agent', 'Task', 'dispatch_agent'). Simple Set lookup, easily extensible. | 2026-03-06 |
|
||||
| Cargo workspace at v2/ level | Extract bterminal-core shared crate for PtyManager + SidecarManager. Workspace members: src-tauri, bterminal-core, bterminal-relay. Enables code reuse between Tauri app and relay binary. | 2026-03-06 |
|
||||
| EventSink trait for event abstraction | Generic trait (emit method) decouples PtyManager/SidecarManager from Tauri. TauriEventSink wraps AppHandle; relay uses WebSocket EventSink. | 2026-03-06 |
|
||||
| bterminal-relay as standalone binary | Rust binary with WebSocket server for remote machine management. Token auth + rate limiting. Per-connection isolated managers. | 2026-03-06 |
|
||||
| RemoteManager WebSocket client | Controller-side WebSocket client in remote.rs. Manages connections to multiple relays with heartbeat ping. 12 new Tauri commands for remote operations. | 2026-03-06 |
|
||||
| Frontend remote routing via remoteMachineId | Pane.remoteMachineId field determines local vs remote. Bridge adapters route to appropriate Tauri commands transparently. | 2026-03-06 |
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **Node.js or Deno for sidecar?** Resolved: Deno-first with Node.js fallback. SidecarCommand struct in sidecar.rs abstracts the choice. Deno preferred (runs TS directly, compiles to single binary). Falls back to Node.js if Deno not in PATH.
|
||||
2. **Multi-machine support?** Designed. See [multi-machine.md](multi-machine.md) for full architecture (bterminal-relay binary, WebSocket NDJSON, RemoteManager). Implementation in 4 phases (A-D).
|
||||
2. **Multi-machine support?** Resolved: Implemented (Phases A-D complete). See [multi-machine.md](multi-machine.md) for architecture. bterminal-core crate extracted, bterminal-relay binary built, RemoteManager + frontend integration done. Remaining: reconnection logic, real-world testing, TLS.
|
||||
3. **Agent Teams integration?** Phase 7 — frontend routing implemented (subagent pane spawning, parent/child navigation). Needs real-world testing with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1.
|
||||
4. **Electron escape hatch threshold?** If Canvas xterm.js proves >50ms latency on target system with 4 panes, switch to Electron. Benchmark in Phase 2.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue