Phase 2: Split pane terminals, custom themes, and password strength meter

Split Pane Layout:
- Add SplitPaneManager with recursive tree-based pane splitting
- Support horizontal (Cmd+Shift+E) and vertical (Cmd+Shift+D) splits
- Draggable resize dividers with 100px minimum pane size
- Hover-visible close button to unsplit panes
- Session picker in new panes for connecting separate terminals
- Automatic xterm refit on all pane resize operations

Custom Terminal Themes:
- Add themes.js with 8 preset colour schemes: Charcoal (default),
  Solarized Dark, Monokai, Nord, Dracula, One Dark, Gruvbox Dark,
  Tokyo Night
- Add TerminalTheme preference to AppPreferences model
- Add colour scheme selector to Settings → Terminal tab
- Live-apply theme changes to all active terminals on save
- TerminalManager now uses themed colours instead of hardcoded values

Master Password Strength Meter:
- Add visual strength bar to vault creation dialog
- Entropy estimation based on length, character diversity, uniqueness
- Four levels: Weak (red), Fair (amber), Good (green), Strong (green)
- Animated transitions on strength changes
- Charcoal-themed CSS matching modal design
This commit is contained in:
2026-04-16 00:00:00 +01:00
parent 5a998aefb9
commit da6320c04b
12 changed files with 1257 additions and 28 deletions
+6
View File
@@ -2,6 +2,7 @@ export namespace models {
export class AppPreferences {
theme: string;
terminalTheme: string;
defaultProtocol: string;
confirmOnClose: boolean;
confirmOnDisconnect: boolean;
@@ -19,6 +20,7 @@ export namespace models {
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.theme = source["theme"];
this.terminalTheme = source["terminalTheme"];
this.defaultProtocol = source["defaultProtocol"];
this.confirmOnClose = source["confirmOnClose"];
this.confirmOnDisconnect = source["confirmOnDisconnect"];
@@ -307,6 +309,8 @@ export namespace models {
keepaliveInterval: number;
keepaliveCountMax: number;
compression: boolean;
agentAuth: boolean;
agentForwarding: boolean;
jumpHosts: JumpHost[];
portForwards: PortForward[];
startupCommand: string;
@@ -327,6 +331,8 @@ export namespace models {
this.keepaliveInterval = source["keepaliveInterval"];
this.keepaliveCountMax = source["keepaliveCountMax"];
this.compression = source["compression"];
this.agentAuth = source["agentAuth"];
this.agentForwarding = source["agentForwarding"];
this.jumpHosts = this.convertValues(source["jumpHosts"], JumpHost);
this.portForwards = this.convertValues(source["portForwards"], PortForward);
this.startupCommand = source["startupCommand"];