BTerminal/docs/v3-progress.md
Hibryda 3ecc4f02d1 docs: update meta files for relative-units rule session
Add session entries to progress logs, update CLAUDE.md files with
rule 18 reference and rem units, archive multi-machine progress
entries, update CHANGELOG/TODO/v3-task_plan with CSS units decision.
2026-03-08 00:27:28 +01:00

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_save Tauri 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 --group CLI 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 call clearAllAgentSessions() + 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', ...))
  • Global settings load on mount via getSetting() from settings-bridge
  • Added imports: onMount, getSetting/setSetting, getCurrentFlavor/setFlavor, CatppuccinFlavor type

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/for label association (e.g., id="theme-flavor", id="default-shell")

CSS Cleanup

  • Removed unused .project-field label selector (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 CatppuccinFlavor type to ThemeId union type (11 values)
  • Added 7 new editor themes: VSCode Dark+, Atom One Dark, Monokai, Dracula, Nord, Solarized Dark, GitHub Dark
  • Added ThemePalette interface (26-color slots) — all themes map to same slots
  • Added ThemeMeta interface (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(): ThemeId replaces getCurrentFlavor() as primary getter
  • setTheme(theme: ThemeId) replaces setFlavor() as primary setter
  • initTheme() validates saved theme against ALL_THEME_IDS
  • Deprecated getCurrentFlavor() and setFlavor() with delegation wrappers

SettingsTab Theme Selector

  • Theme dropdown uses <optgroup> per theme group (Catppuccin, Editor)
  • themeGroups derived from THEME_LIST using Map grouping
  • handleThemeChange() replaces direct setFlavor() call
  • Fixed input overflow in .setting-row with min-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 ThemeId union type from 11 to 17 values
  • Added THEME_LIST entries with group: '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 getPalette import 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: 180px on .theme-dropdown container (was min-width: 0) to prevent trigger from collapsing
  • Set min-width: 280px on .theme-options dropdown menu (was right: 0) to ensure full theme names visible
  • Increased max-height from 320px to 400px on dropdown menu for better scrolling experience
  • Added white-space: nowrap on .theme-option-label (was min-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_size keys)
  • handleFontFamilyChange() and handleFontSizeChange() functions with validation

SettingsTab Layout Restructure

  • Restructured global settings from inline .setting-row (label left, control right) to 2-column .global-grid with .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-family and --ui-font-size to catppuccin.css :root (defaults: JetBrains Mono fallback chain, 13px)
  • Updated app.css body rule to use CSS vars instead of hardcoded font values

Theme Store Font Restoration

  • Extended initTheme() in theme.svelte.ts to load and apply saved font_family and font_size settings 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 icons record 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-row flex 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: 1 to height: 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 panelTitles record 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-family and --term-font-size CSS 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

Session: 2026-03-08 — CSS Relative Units Rule

New Rule: 18-relative-units.md

  • Created .claude/rules/18-relative-units.md enforcing rem/em for layout CSS
  • Pixels allowed only for icon sizes, borders/outlines, box shadows
  • Exception: --ui-font-size/--term-font-size CSS vars store px (xterm.js API requirement)
  • Added rule #18 to .claude/CLAUDE.md rule index

CSS Conversions

  • GlobalTabBar.svelte: rail width 36px -> 2.75rem, button 28px -> 2rem, gap 2px -> 0.25rem, padding 6px 4px -> 0.5rem 0.375rem, border-radius 4px -> 0.375rem
  • App.svelte: sidebar header padding 8px 12px -> 0.5rem 0.75rem, close button 22px -> 1.375rem, border-radius 4px -> 0.25rem
  • Also changed GlobalTabBar rail-btn color from --ctp-overlay1 to --ctp-subtext0 for better contrast