8.4 KiB
8.4 KiB
BTerminal v2 — Implementation Phases
See task_plan.md for architecture decisions, error handling, and testing strategy.
Phase 1: Project Scaffolding [status: complete] — MVP
- Create feature branch
v2-mission-control - Initialize Tauri 2.x project with Svelte 5 frontend
- Project structure (see below)
- Basic Tauri window with Catppuccin Mocha CSS variables
- Verify Tauri builds and launches on target system
- Set up dev scripts (dev, build, lint)
File Structure
bterminal-v2/
src-tauri/
src/
main.rs # Tauri app entry
pty.rs # PTY management (portable-pty, not plugin)
sidecar.rs # Node.js sidecar lifecycle (spawn, restart, health)
watcher.rs # File watcher for markdown viewer
session.rs # Session persistence (SQLite via rusqlite)
Cargo.toml
src/
App.svelte # Root layout
lib/
components/
Layout/
TilingGrid.svelte # Dynamic tiling manager
PaneContainer.svelte # Individual pane wrapper
PaneHeader.svelte # Pane title bar with controls
Terminal/
TerminalPane.svelte # xterm.js terminal pane
Agent/
AgentPane.svelte # SDK agent structured output
AgentTree.svelte # Subagent tree visualization (SVG)
Markdown/
MarkdownPane.svelte # Live markdown file viewer
Sidebar/
SessionList.svelte # Session browser
StatusBar/
StatusBar.svelte # Global status bar (pane counts, cost)
Notifications/
ToastContainer.svelte # Toast notification display
Settings/
SettingsDialog.svelte # Settings modal dialog
stores/
sessions.svelte.ts # Session state ($state runes)
agents.svelte.ts # Active agent tracking
layout.svelte.ts # Pane layout state
notifications.svelte.ts # Toast notification state
adapters/
sdk-messages.ts # SDK message abstraction layer
pty-bridge.ts # PTY IPC wrapper
settings-bridge.ts # Settings IPC wrapper
utils/
agent-tree.ts # Agent tree builder (hierarchy from messages)
styles/
catppuccin.css # Theme CSS variables
app.css
sidecar/
agent-runner.ts # Node.js sidecar entry point
package.json # Agent SDK dependency
esbuild.config.ts # Bundle to single file
package.json
svelte.config.js
vite.config.ts
tauri.conf.json
Key change from v1: Using portable-pty directly from Rust instead of tauri-plugin-pty (38-star community plugin). portable-pty is well-maintained (used by WezTerm). More work upfront, more reliable long-term.
Phase 2: Terminal Pane + Layout [status: complete] — MVP
Layout (responsive)
32:9 (5120px) — full density:
+--------+------------------------------------+--------+
|Sidebar | 2-4 panes, CSS Grid, resizable | Right |
| 260px | | 380px |
+--------+------------------------------------+--------+
16:9 (1920px) — degraded but functional:
+--------+-------------------------+
|Sidebar | 1-2 panes | (right panel collapses to overlay)
| 240px | |
+--------+-------------------------+
- CSS Grid layout with sidebar + main area + optional right panel
- Responsive breakpoints (ultrawide / standard / narrow)
- Pane resize via drag handles (deferred — current presets sufficient for MVP)
- Layout presets: 1-col, 2-col, 3-col, 2x2, master+stack
- Save/restore layout to SQLite (Phase 4)
- Keyboard: Ctrl+1-4 focus pane, Ctrl+N new terminal
Terminal
- xterm.js with Canvas addon (explicit — no WebGL dependency)
- Catppuccin Mocha theme for xterm.js
- PTY spawn from Rust (portable-pty), stream to frontend via Tauri events
- Terminal resize -> PTY resize (100ms debounce)
- Copy/paste (Ctrl+Shift+C/V) — deferred
- SSH session: spawn
sshcommand in PTY (via shell args) - Local shell: spawn user's $SHELL
- Claude Code CLI: spawn
claudein PTY (via shell args)
Milestone: After Phase 2, we have a working multi-pane terminal. Usable as a daily driver even without agent features.
Phase 3: Agent SDK Integration [status: complete] — MVP
Backend
- Node.js sidecar: spawns
claudeCLI with--output-format stream-json(not Agent SDK query() — avoids npm dep + version churn) - Sidecar communication: Rust spawns Node.js, stdio NDJSON
- Sidecar lifecycle: auto-start on app launch, shutdown on exit
- Sidecar lifecycle: detect crash, offer restart in UI (agent_restart command + restart button)
- Tauri commands: agent_query, agent_stop, agent_ready, agent_restart
Frontend
- SDK message adapter: parses stream-json into 9 typed AgentMessage types (abstraction layer)
- Agent bridge: Tauri IPC adapter (invoke + event listeners)
- Agent dispatcher: singleton routing sidecar events to store, crash detection
- Agent store: session state, message history, cost tracking (Svelte 5 $state)
- Agent pane: renders structured messages
- Text -> plain text (markdown rendering deferred)
- Tool calls -> collapsible cards (tool name + input)
- Tool results -> collapsible cards
- Thinking -> collapsible details
- Init -> model badge
- Cost -> USD/tokens/turns/duration summary
- Errors -> highlighted error card
- Subagent spawn -> tree node + optional new pane (Phase 5)
- Agent status indicator (starting/running/done/error)
- Start/stop agent from UI (prompt form + stop button)
- Auto-scroll with scroll-lock on user scroll-up
- Session resume (SDK
resume: sessionId) - Keyboard: Ctrl+Shift+N new agent
- Sidebar: agent session button
Milestone: After Phase 3, we have the core differentiator. SDK agents run in structured panes alongside raw terminals.
Phase 4: Session Management + Markdown Viewer [status: complete] — MVP
Sessions
- SQLite persistence for sessions (rusqlite with bundled feature)
- Session types: terminal, agent, markdown (SSH via terminal args)
- Session CRUD: save, delete, update_title, touch (last_used_at)
- Session groups/folders (deferred — not needed for MVP)
- Remember last layout on restart (preset + pane_ids in layout_state table)
- Auto-restore panes on app startup (restoreFromDb in layout store)
Markdown Viewer
- File watcher (notify crate v6) -> Tauri events -> frontend
- Markdown rendering (marked.js)
- Syntax highlighting (Shiki) — deferred, adds significant bundle size
- Open from sidebar (file picker button "M")
- Catppuccin-themed markdown styles (h1-h3, code, pre, tables, blockquotes)
- Live reload on file change
Milestone: After Phase 4 = MVP ship. Full session management, structured agent panes, terminal panes, markdown viewer.
Phase 5: Agent Tree + Polish [status: in_progress] — Post-MVP
- Agent tree visualization (SVG, compact horizontal layout) — AgentTree.svelte + agent-tree.ts utility
- Click tree node -> focus agent pane (onNodeClick prop exists, not wired)
- Aggregate cost per subtree (subtreeCost util exists, not displayed in UI)
- Global status bar (terminal/agent counts, active agents pulse, token/cost totals) — StatusBar.svelte
- Notification system (toast: success/error/warning/info, auto-dismiss 4s, max 5) — notifications.svelte.ts + ToastContainer.svelte
- Agent dispatcher toast integration (agent complete, error, sidecar crash notifications)
- Global keyboard shortcuts — Ctrl+W close focused pane, Ctrl+, open settings
- Settings dialog (default shell, cwd, max panes) — SettingsDialog.svelte + settings-bridge.ts
- Settings backend — settings table in SQLite (session.rs), Tauri commands settings_get/set/list (lib.rs)
- ctx integration (port from v1)
Phase 6: Packaging + Distribution [status: not_started] — Post-MVP
- install.sh v2 (check Node.js, install Tauri runtime deps)
- AppImage build (single file, works everywhere)
- .deb package (Debian/Ubuntu)
- GitHub Actions CI for building releases
- Auto-update mechanism (Tauri updater)
- Migrate bterminal.svg icon
- README update
System Requirements
- Node.js 20+ (for Agent SDK sidecar)
- WebKit2GTK 4.1+ (Tauri runtime)
- Linux x86_64 (primary target)