16 KiB
16 KiB
BTerminal v3 — Progress Log
Session: 2026-03-07 — Architecture Planning + MVP Implementation (Phases 1-5)
Phase: Adversarial Design Review
- Launch 3 architecture agents (Architect, Devil's Advocate, UX+Performance Specialist)
- Collect findings — 12 issues identified, all resolved
- Produce final architecture plan in docs/v3-task_plan.md
- Create 10-phase implementation plan
Phase 1: Data Model + Config
- Created
v2/src/lib/types/groups.ts— TypeScript interfaces (ProjectConfig, GroupConfig, GroupsFile) - Created
v2/src-tauri/src/groups.rs— Rust structs + load/save groups.json - Added
groups_load,groups_saveTauri commands to lib.rs - SQLite migrations in session.rs: project_id column, agent_messages table, project_agent_state table
- Created
v2/src/lib/adapters/groups-bridge.ts(IPC wrapper) - Created
v2/src/lib/stores/workspace.svelte.ts(replaces layout.svelte.ts, Svelte 5 runes) - Added
--groupCLI argument parsing in main.rs - Wrote 24 vitest tests for workspace store (workspace.test.ts)
- Wrote cargo tests for groups load/save/default
Phase 2: Project Box Shell
- Created GlobalTabBar.svelte (Sessions | Docs | Context | Settings)
- Created ProjectGrid.svelte (flex + scroll-snap container)
- Created ProjectBox.svelte (CSS grid: header | session-area | terminal-area)
- Created ProjectHeader.svelte (icon + name + status dot + accent color)
- Rewrote App.svelte (GlobalTabBar + tab content + StatusBar, no sidebar/TilingGrid)
- Created CommandPalette.svelte (Ctrl+K overlay with fuzzy search)
- Created DocsTab.svelte (markdown file browser per project)
- Created ContextTab.svelte (wrapper for ContextPane)
- Created SettingsTab.svelte (per-project + global settings editor)
- CSS for responsive project count + Catppuccin accent colors
Phase 3: Claude Session Integration
- Created ClaudeSession.svelte (wraps AgentPane, passes project cwd/profile/config_dir)
Phase 4: Terminal Tabs
- Created TerminalTabs.svelte (tab bar + content, shell/SSH/agent tab types)
Phase 5: Team Agents Panel
- Created TeamAgentsPanel.svelte (right panel for subagents)
- Created AgentCard.svelte (compact subagent view: status, messages, cost)
Bug Fix
- Fixed AgentPane Svelte 5 event modifier syntax:
on:click->onclick(Svelte 5 requires lowercase event attributes)
Verification
- All 138 vitest tests pass (114 existing + 24 new workspace tests)
- All 36 cargo tests pass (29 existing + 7 new groups tests)
- Vite build succeeds
Session: 2026-03-07 — Phases 6-10 Completion
Phase 6: Session Continuity
- Added
persistSessionForProject()to agent-dispatcher — saves agent state + messages to SQLite on session complete - Added
registerSessionProject()— maps sessionId -> projectId for persistence routing - Added
sessionProjectMap(Map<string, string>) in agent-dispatcher - Updated ClaudeSession.svelte:
restoreMessagesFromRecords()restores cached messages into agent store on mount - ClaudeSession loads previous state via
loadProjectAgentState(), restores session ID and messages - Added
getAgentSession()export to agents store
Phase 7: Workspace Teardown on Group Switch
- Added
clearAllAgentSessions()to agents store (clears sessions array) - Updated
switchGroup()in workspace store to callclearAllAgentSessions()+ reset terminal tabs - Updated workspace.test.ts to mock
clearAllAgentSessions
Phase 10: Dead Component Removal + Polish
- Deleted
TilingGrid.svelte(328 lines),PaneContainer.svelte(113 lines),PaneHeader.svelte(44 lines) - Deleted
SessionList.svelte(374 lines),SshSessionList.svelte(263 lines),SshDialog.svelte(281 lines),SettingsDialog.svelte(433 lines) - Removed empty directories: Layout/, Sidebar/, Settings/, SSH/
- Rewrote StatusBar.svelte for workspace store (group name, project count, agent count, "BTerminal v3" label)
- Fixed subagent routing in agent-dispatcher: project-scoped sessions skip layout pane creation (subagents render in TeamAgentsPanel instead)
- Updated v3-task_plan.md to mark all 10 phases complete
Verification
- All 138 vitest tests pass (including updated workspace tests with clearAllAgentSessions mock)
- All 36 cargo tests pass
- Vite build succeeds
- ~1,836 lines of dead code removed
Session: 2026-03-07 — SettingsTab Global Settings + Cleanup
SettingsTab Global Settings Section
- Added "Global" section to SettingsTab.svelte with three settings:
- Theme flavor dropdown (Catppuccin Latte/Frappe/Macchiato/Mocha) via
setFlavor()from theme store - Default shell text input (persisted via
setSetting('default_shell', ...)) - Default CWD text input (persisted via
setSetting('default_cwd', ...))
- Theme flavor dropdown (Catppuccin Latte/Frappe/Macchiato/Mocha) via
- Global settings load on mount via
getSetting()from settings-bridge - Added imports:
onMount,getSetting/setSetting,getCurrentFlavor/setFlavor,CatppuccinFlavortype
A11y Fixes
- Changed project field labels from
<div class="project-field"><label>to wrapping<label class="project-field"><span class="field-label">pattern — proper label/input association - Global settings use
id/forlabel association (e.g.,id="theme-flavor",id="default-shell")
CSS Cleanup
- Removed unused
.project-field labelselector (replaced by.field-label) - Simplified
.project-field input[type="text"], .project-field input:not([type])to.project-field input:not([type="checkbox"])
Rust Cleanup (committed separately)
- Removed dead
update_ssh_session()method from session.rs and its test - Fixed stale TilingGrid comment in AgentPane.svelte
Session: 2026-03-07 — Multi-Theme System (7 Editor Themes)
Theme System Generalization
- Generalized
CatppuccinFlavortype toThemeIdunion type (11 values) - Added 7 new editor themes: VSCode Dark+, Atom One Dark, Monokai, Dracula, Nord, Solarized Dark, GitHub Dark
- Added
ThemePaletteinterface (26-color slots) — all themes map to same slots - Added
ThemeMetainterface (id, label, group, isDark) for UI metadata - Added
THEME_LIST: ThemeMeta[]with group metadata ('Catppuccin' or 'Editor') - Added
ALL_THEME_IDS: ThemeId[]derived from THEME_LIST for validation - Deprecated
CatppuccinFlavor,CatppuccinPalette,FLAVOR_LABELS,ALL_FLAVORS(kept as backwards compat aliases)
Theme Store Updates
getCurrentTheme(): ThemeIdreplacesgetCurrentFlavor()as primary gettersetTheme(theme: ThemeId)replacessetFlavor()as primary setterinitTheme()validates saved theme againstALL_THEME_IDS- Deprecated
getCurrentFlavor()andsetFlavor()with delegation wrappers
SettingsTab Theme Selector
- Theme dropdown uses
<optgroup>per theme group (Catppuccin, Editor) themeGroupsderived fromTHEME_LISTusing Map groupinghandleThemeChange()replaces directsetFlavor()call- Fixed input overflow in
.setting-rowwithmin-width: 0
Design Decision
All editor themes map to the same --ctp-* CSS custom property names (26 vars). This means every component works unchanged — no component-level theme awareness needed. Each theme provides its own mapping of colors to the 26 semantic slots.
Verification
- All 138 vitest + 35 cargo tests pass
Session: 2026-03-07 — Deep Dark Theme Group (6 Themes)
New Theme Group: Deep Dark
- Added 6 new "Deep Dark" themes to
v2/src/lib/styles/themes.ts:- Tokyo Night (base: #1a1b26)
- Gruvbox Dark (base: #1d2021)
- Ayu Dark (base: #0b0e14, near-black)
- Poimandres (base: #1b1e28)
- Vesper (base: #101010, warm dark)
- Midnight (base: #000000, pure OLED black)
- Extended
ThemeIdunion type from 11 to 17 values - Added
THEME_LISTentries withgroup: 'Deep Dark' - Added all 6 palette definitions (26 colors each) mapped to --ctp-* slots
- Total themes: 17 across 3 groups (Catppuccin 4, Editor 7, Deep Dark 6)
Verification
- No test changes needed — theme palettes are data-only, no logic changes
Session: 2026-03-07 — Custom Theme Dropdown
SettingsTab Theme Picker Redesign
- Replaced native
<select>with custom themed dropdown in SettingsTab.svelte - Dropdown trigger shows color swatch (base color from getPalette()) + theme label + arrow indicator
- Dropdown menu groups themes by category (Catppuccin/Editor/Deep Dark) with styled uppercase headers
- Each option shows: color swatch + label + 4 accent color dots (red/green/blue/yellow)
- Active theme highlighted with surface0 background + bold text
- Click-outside handler and Escape key to close dropdown
- Uses --ctp-* CSS vars throughout — fully themed with any active theme
- Added
getPaletteimport from themes.ts for live color rendering - Added aria-haspopup/aria-expanded attributes for accessibility
Verification
- No test changes needed — UI-only change, no logic changes
Session: 2026-03-07 — Theme Dropdown CSS Polish
SettingsTab Dropdown Sizing Fix
- Set
min-width: 180pxon.theme-dropdowncontainer (wasmin-width: 0) to prevent trigger from collapsing - Set
min-width: 280pxon.theme-optionsdropdown menu (wasright: 0) to ensure full theme names visible - Increased
max-heightfrom 320px to 400px on dropdown menu for better scrolling experience - Added
white-space: nowrapon.theme-option-label(wasmin-width: 0) to prevent label text wrapping
Verification
- No test changes needed — CSS-only change
Session: 2026-03-07 — Global Font Controls
SettingsTab Font Family + Font Size Controls
- Added font family
<select>with 9 monospace font options (JetBrains Mono, Fira Code, Cascadia Code, Source Code Pro, IBM Plex Mono, Hack, Inconsolata, Ubuntu Mono, monospace) + "Default" option - Added font size +/- stepper control with numeric input (range 8-24px)
- Both controls apply live preview via CSS custom properties (
--ui-font-family,--ui-font-size) - Both settings persisted to SQLite via settings-bridge (
font_family,font_sizekeys) handleFontFamilyChange()andhandleFontSizeChange()functions with validation
SettingsTab Layout Restructure
- Restructured global settings from inline
.setting-row(label left, control right) to 2-column.global-gridwith.setting-field(label above control) - Labels now uppercase, 0.7rem, subtext0 color — consistent compact labeling
- All inputs/selects use consistent styling (surface0 bg, surface1 border, 4px radius)
CSS Typography Variables
- Added
--ui-font-familyand--ui-font-sizeto catppuccin.css:root(defaults: JetBrains Mono fallback chain, 13px) - Updated
app.cssbody rule to use CSS vars instead of hardcoded font values
Theme Store Font Restoration
- Extended
initTheme()intheme.svelte.tsto load and apply savedfont_familyandfont_sizesettings on startup - Font restoration wrapped in try/catch — failures are non-fatal (CSS defaults apply)
Verification
- No test changes needed — UI/CSS-only changes, no logic changes
Session: 2026-03-07 — Settings Drawer Conversion
Settings Tab to Drawer
- Converted Settings from a full-page tab to a collapsible side drawer
- GlobalTabBar now has 3 tabs (Sessions/Docs/Context) + gear icon toggle for settings drawer
- App.svelte renders SettingsTab in an
<aside>drawer (right side, 32em width, semi-transparent backdrop) - Drawer close: Escape key, click-outside (backdrop), close button (X icon)
- Gear icon in GlobalTabBar highlights blue when drawer is open (active state)
- GlobalTabBar accepts props:
settingsOpen,ontoggleSettings - Removed 'settings' from WorkspaceTab union type (now 'sessions' | 'docs' | 'context')
- Alt+1..3 for tabs (was Alt+1..4), Ctrl+, toggles drawer (was setActiveTab('settings'))
- SettingsTab padding reduced (12px 16px), max-width removed, flex:1 for drawer context
Verification
- All 138 vitest tests pass
Session: 2026-03-08 — VSCode-Style Sidebar Redesign
UI Layout Redesign (Top Tab Bar -> Left Sidebar)
- Redesigned GlobalTabBar.svelte from horizontal tab bar to vertical icon rail (36px wide)
- 4 SVG icon buttons: Sessions (grid), Docs (document), Context (clock), Settings (gear)
- Each button uses SVG path from
iconsrecord mapped by WorkspaceTab - Props renamed:
settingsOpen->expanded,ontoggleSettings->ontoggle handleTabClick()manages toggle: clicking active tab collapses drawer
- Rewrote App.svelte layout from vertical (top tab bar + content area + settings drawer) to horizontal (icon rail + sidebar panel + workspace)
.main-rowflex container: GlobalTabBar | sidebar-panel (28em, max 50%) | workspace- ProjectGrid always visible in main workspace (not inside tab content)
- Sidebar panel renders active tab content (Sessions/Docs/Context/Settings)
- Panel header with title + close button
- Removed backdrop overlay, drawer is inline sidebar not overlay
- Re-added 'settings' to WorkspaceTab union type (was removed when settings was a drawer)
- SettingsTab CSS: changed
flex: 1toheight: 100%for sidebar panel context - Updated keyboard shortcuts:
- Alt+1..4 (was Alt+1..3): switch tabs + open drawer, toggle if same tab
- Ctrl+B (new): toggle sidebar open/closed
- Ctrl+, : open settings panel (toggle if already active)
- Escape: close drawer
- State variables renamed:
settingsOpen->drawerOpen,toggleSettings()->toggleDrawer() - Added
panelTitlesrecord for drawer header labels
Design Decisions
- VSCode-style sidebar chosen for: always-visible workspace, progressive disclosure, familiar UX
- Settings as regular tab (not special drawer) simplifies code and mental model
- Icon rail at 36px minimizes horizontal space cost
- No backdrop overlay — sidebar is inline, not modal
Verification
- All 138 vitest tests pass
- svelte-check clean (only 2 third-party esrap warnings)
Session: 2026-03-07 — SettingsTab Global Settings Redesign
Font Settings Split (UI Font + Terminal Font)
- Split single font setting into UI font (sans-serif options) and Terminal font (monospace options)
- UI font dropdown: System Sans-Serif, Inter, Roboto, Open Sans, Lato, Noto Sans, Source Sans 3, IBM Plex Sans, Ubuntu + Default
- Terminal font dropdown: JetBrains Mono, Fira Code, Cascadia Code, Source Code Pro, IBM Plex Mono, Hack, Inconsolata, Ubuntu Mono, monospace + Default
- Each font dropdown renders preview text in its own typeface
- Size steppers (8-24px) for both UI and Terminal font independently
- Changed setting keys: font_family -> ui_font_family, font_size -> ui_font_size, + new term_font_family, term_font_size
SettingsTab Layout Redesign
- Rewrote global settings as single-column layout with labels above controls
- Split into "Appearance" subsection (theme, UI font, terminal font) and "Defaults" subsection (shell, CWD)
- All dropdowns now use reusable custom themed dropdowns (no native
<select>anywhere)
CSS + Theme Store Updates
- Added
--term-font-familyand--term-font-sizeCSS custom properties to catppuccin.css - Updated
initTheme()in theme.svelte.ts: loads 4 font settings (ui_font_family, ui_font_size, term_font_family, term_font_size) instead of 2 - UI font fallback changed from monospace to sans-serif
Verification
- No test changes needed — UI/CSS-only changes, no logic changes