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:
Hibryda 2026-03-06 19:06:00 +01:00
parent 5503340e87
commit 0a17c09a46
8 changed files with 184 additions and 40 deletions

View file

@ -4,7 +4,7 @@
- v1 is a single-file Python app (`bterminal.py`). Changes are localized.
- v2 docs are in `docs/`. Architecture decisions are in `docs/task_plan.md`.
- Phases 1-7 complete. Extras: SSH, ctx, themes, detached mode, auto-updater, shiki, copy/paste, session resume, drag-resize, session groups, Deno sidecar, 114 vitest + 29 cargo tests.
- Phases 1-7 + multi-machine (A-D) complete. Extras: SSH, ctx, themes, detached mode, auto-updater, shiki, copy/paste, session resume, drag-resize, session groups, Deno sidecar, 114 vitest + 29 cargo tests.
- Consult Memora (tag: `bterminal`) before making architectural changes.
## Documentation References
@ -43,6 +43,12 @@
- Theme flavors (Latte/Frappe/Macchiato/Mocha) override CSS variables at runtime. Open terminals hot-swap via onThemeChange() callback registry in theme.svelte.ts.
- Detached pane mode: App.svelte checks URL param `?detached=1` and renders a single pane without sidebar/grid chrome. Used for pop-out windows.
- Shiki syntax highlighting uses lazy singleton pattern (avoid repeated WASM init). 13 languages preloaded. Used in MarkdownPane and AgentPane text messages.
- Cargo workspace at v2/ level: members = [src-tauri, bterminal-core, bterminal-relay]. Cargo.lock is at workspace root (v2/), not in src-tauri/.
- EventSink trait (bterminal-core/src/event.rs) abstracts event emission. PtyManager and SidecarManager are in bterminal-core, not src-tauri. src-tauri has thin re-exports.
- RemoteManager (src-tauri/src/remote.rs) manages WebSocket client connections to bterminal-relay instances. 12 Tauri commands prefixed with `remote_`.
- remote-bridge.ts adapter wraps remote machine management IPC. machines.svelte.ts store tracks remote machine state.
- Pane.remoteMachineId?: string routes operations through RemoteManager instead of local managers. Bridge adapters (pty-bridge, agent-bridge) check this field.
- bterminal-relay binary (v2/bterminal-relay/) is a standalone WebSocket server with token auth, rate limiting, and per-connection isolated managers.
## Memora Tags

View file

@ -8,7 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Multi-machine support architecture design (`docs/multi-machine.md`): bterminal-relay binary, WebSocket NDJSON protocol, RemoteManager, pre-shared token + TLS auth, autonomous relay model, 4-phase implementation plan (A: extract bterminal-core crate, B: relay binary, C: RemoteManager, D: frontend integration)
- bterminal-core shared crate with EventSink trait: extracted PtyManager and SidecarManager into reusable crate at v2/bterminal-core/, EventSink trait abstracts event emission for both Tauri and WebSocket contexts
- bterminal-relay WebSocket server binary: standalone Rust binary at v2/bterminal-relay/ with token auth (--port, --token, --insecure CLI flags), rate limiting (10 attempts, 5min lockout), per-connection isolated PTY + sidecar managers
- RemoteManager for multi-machine WebSocket connections: v2/src-tauri/src/remote.rs manages WebSocket client connections to relay instances, 12 new Tauri commands for remote operations, heartbeat ping every 15s
- Remote machine management UI in settings: SettingsDialog "Remote Machines" section for add/remove/connect/disconnect
- Auto-grouping of remote panes in sidebar: remote panes auto-grouped by machine label in SessionList
- remote-bridge.ts adapter for remote machine IPC operations
- machines.svelte.ts store for remote machine state management (Svelte 5 runes)
- Pane.remoteMachineId field in layout store for local vs remote routing
- TauriEventSink (event_sink.rs) implementing EventSink trait for Tauri AppHandle
- Multi-machine support architecture design (`docs/multi-machine.md`): WebSocket NDJSON protocol, pre-shared token + TLS auth, autonomous relay model
- Subagent cost aggregation: getTotalCost() recursive helper in agents store aggregates cost across parent + all child sessions; total cost displayed in parent pane done-bar when children present
- 10 new subagent routing tests in agent-dispatcher.test.ts: spawn, dedup, child message routing, init/cost forwarding, fallbacks (28 total dispatcher tests, 114 vitest tests overall)
- TAURI_SIGNING_PRIVATE_KEY secret set in GitHub repo for auto-update signing
@ -35,6 +44,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- tempfile dev dependency for Rust test isolation
### Changed
- PtyManager and SidecarManager extracted from src-tauri to bterminal-core shared crate (src-tauri now has thin re-export wrappers)
- Cargo workspace structure at v2/ level: members = [src-tauri, bterminal-core, bterminal-relay], Cargo.lock moved from src-tauri/ to workspace root
- agent-bridge.ts and pty-bridge.ts extended with remote routing (check remoteMachineId, route to remote_* commands)
- Agent dispatcher refactored to split messages: parentId-bearing messages routed to child panes via toolUseToChildPane Map, main session messages stay in parent
- Agent store createAgentSession() now accepts optional parent parameter for registering bidirectional parent/child links
- Agent store removeAgentSession() cleans up parent's childSessionIds on removal

View file

@ -2,7 +2,7 @@
Terminal with session panel (MobaXterm-style), built with GTK 3 + VTE. Catppuccin Mocha theme.
> **v2 Phases 1-7 complete:** Multi-session Claude agent dashboard using Tauri 2.x + Svelte 5. Features: multi-pane terminal with PTY backend and copy/paste, agent panes with structured output, tree visualization with subtree cost and session resume, **subagent/agent-teams support** (auto-spawns child panes for subagents with parent/child navigation and recursive cost aggregation), session groups/folders with collapsible sidebar headers, SSH session management, ctx context database viewer, SQLite session persistence with layout restore, live markdown file viewer with Shiki syntax highlighting, global status bar with cost tracking, toast notifications, settings dialog with theme flavors (Catppuccin Latte/Frappe/Macchiato/Mocha) and live hot-swap, detached pane mode (pop-out windows), pane drag-resize handles, auto-updater plugin with signing key configured, Deno-first sidecar with Node.js fallback, CSS Grid tiling, .deb + AppImage packaging, GitHub Actions CI, 114 vitest + 29 cargo tests. Branch `v2-mission-control`. See [docs/task_plan.md](docs/task_plan.md) for architecture and [docs/phases.md](docs/phases.md) for implementation plan.
> **v2 Phases 1-7 + Multi-Machine (A-D) complete:** Multi-session Claude agent dashboard using Tauri 2.x + Svelte 5. Features: multi-pane terminal with PTY backend and copy/paste, agent panes with structured output, tree visualization with subtree cost and session resume, **subagent/agent-teams support** (auto-spawns child panes for subagents with parent/child navigation and recursive cost aggregation), **multi-machine support** (bterminal-relay WebSocket server + RemoteManager for managing agents/terminals on remote machines), session groups/folders with collapsible sidebar headers, SSH session management, ctx context database viewer, SQLite session persistence with layout restore, live markdown file viewer with Shiki syntax highlighting, global status bar with cost tracking, toast notifications, settings dialog with theme flavors (Catppuccin Latte/Frappe/Macchiato/Mocha) and live hot-swap, detached pane mode (pop-out windows), pane drag-resize handles, auto-updater plugin with signing key configured, Deno-first sidecar with Node.js fallback, CSS Grid tiling, .deb + AppImage packaging, GitHub Actions CI, 114 vitest + 29 cargo tests. Branch `v2-mission-control`. See [docs/task_plan.md](docs/task_plan.md) for architecture and [docs/phases.md](docs/phases.md) for implementation plan.
![BTerminal](screenshot.png)
@ -109,6 +109,37 @@ Context database: `~/.claude-context/context.db`
| `Ctrl+Shift+V` | Paste |
| `Ctrl+PageUp/Down` | Previous/next tab |
## Multi-Machine Support (v2)
BTerminal v2 can manage agents and terminals running on remote machines via the `bterminal-relay` binary.
### Architecture
```
BTerminal (Controller) --WebSocket--> bterminal-relay (Remote Machine)
├── PtyManager (remote terminals)
└── SidecarManager (remote agents)
```
### Running the Relay
On each remote machine:
```bash
# Build the relay binary
cd v2 && cargo build --release -p bterminal-relay
# Start with token auth
./target/release/bterminal-relay --port 9750 --token <secret>
# Dev mode (allow unencrypted ws://)
./target/release/bterminal-relay --port 9750 --token <secret> --insecure
```
Add remote machines in BTerminal Settings > Remote Machines (label, URL, token). Remote panes auto-group by machine label in the sidebar.
See [docs/multi-machine.md](docs/multi-machine.md) for full architecture details.
## Documentation
| Document | Description |

View file

@ -4,11 +4,15 @@
- [ ] **Deno sidecar real-world testing** -- Integrated into sidecar.rs (Deno-first + Node.js fallback). Needs testing with real claude CLI and startup time benchmark vs Node.js.
- [ ] **E2E testing (Playwright/WebDriver)** -- Scaffold at v2/tests/e2e/README.md. Needs display server to run. Test: open terminal, run command, open agent, verify output.
- [ ] **Multi-machine support** -- Architecture designed in [docs/multi-machine.md](docs/multi-machine.md). Next: Phase A (extract bterminal-core crate), then Phase B (bterminal-relay binary).
- [ ] **Multi-machine reconnection** -- Implement exponential backoff reconnection logic (1s-30s cap) in RemoteManager for dropped WebSocket connections.
- [ ] **Multi-machine real-world testing** -- Test bterminal-relay with 2 machines (local + 1 remote). Verify PTY + agent operations over WebSocket.
- [ ] **Multi-machine TLS/certificate pinning** -- Add TLS support to bterminal-relay and certificate pinning in RemoteManager for production security.
- [ ] **Agent Teams real-world testing** -- Frontend routing implemented (Phase 7). Needs testing with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 and real subagent spawning.
## Completed
- [x] **Multi-machine support (Phases A-D)** -- bterminal-core crate extraction, bterminal-relay WebSocket binary, RemoteManager, frontend integration. | Done: 2026-03-06
- [x] **Set TAURI_SIGNING_PRIVATE_KEY secret** -- Set via `gh secret set` on DexterFromLab/BTerminal. | Done: 2026-03-06
- [x] **Dispatcher tests for subagent routing** -- 10 new tests covering spawn, dedup, child message routing, init/cost forwarding, fallbacks. Total: 28 dispatcher tests. | Done: 2026-03-06
- [x] **Subagent cost aggregation** -- `getTotalCost()` recursive helper in agents store, total cost shown in parent pane done-bar when children present. | Done: 2026-03-06

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.