feat(v2): add SSH management, ctx integration, themes, detached mode, auto-updater

SSH session management:
- SshSession struct + ssh_sessions SQLite table in session.rs
- CRUD Tauri commands (ssh_session_list/save/delete) in lib.rs
- SshDialog.svelte (create/edit modal), SshSessionList.svelte (sidebar)
- SSH pane routes to TerminalPane with shell=/usr/bin/ssh + args

ctx context database integration:
- ctx.rs: read-only CtxDb (SQLITE_OPEN_READ_ONLY for ~/.claude-context/context.db)
- 5 Tauri commands (ctx_list_projects/get_context/get_shared/get_summaries/search)
- ContextPane.svelte with project selector, tabs, search
- ctx-bridge.ts adapter

Catppuccin theme flavors (Latte/Frappe/Macchiato/Mocha):
- themes.ts: all 4 palette definitions + buildXtermTheme/applyCssVariables
- theme.svelte.ts: reactive store with SQLite persistence
- SettingsDialog flavor dropdown, TerminalPane theme-aware

Detached pane mode (pop-out windows):
- detach.ts: isDetachedMode/getDetachedConfig from URL params
- App.svelte: conditional rendering of single pane without chrome

Other additions:
- Shiki syntax highlighting (highlight.ts, lazy singleton, 13 languages)
- Tauri auto-updater plugin (tauri-plugin-updater + updater.ts)
- AgentPane markdown rendering with Shiki code highlighting
- New deps: shiki, @tauri-apps/plugin-updater, tauri-plugin-updater
This commit is contained in:
Hibryda 2026-03-06 14:50:00 +01:00
parent 4f2614186d
commit 4db7ccff60
28 changed files with 2992 additions and 51 deletions

View file

@ -11,7 +11,7 @@ import {
export type LayoutPreset = '1-col' | '2-col' | '3-col' | '2x2' | 'master-stack';
export type PaneType = 'terminal' | 'agent' | 'markdown' | 'empty';
export type PaneType = 'terminal' | 'agent' | 'markdown' | 'ssh' | 'context' | 'empty';
export interface Pane {
id: string;

View file

@ -0,0 +1,47 @@
// Theme store — persists Catppuccin flavor selection via settings bridge
import { getSetting, setSetting } from '../adapters/settings-bridge';
import {
type CatppuccinFlavor,
buildXtermTheme,
applyCssVariables,
type XtermTheme,
} from '../styles/themes';
let currentFlavor = $state<CatppuccinFlavor>('mocha');
export function getCurrentFlavor(): CatppuccinFlavor {
return currentFlavor;
}
export function getXtermTheme(): XtermTheme {
return buildXtermTheme(currentFlavor);
}
/** Change flavor, apply CSS variables, and persist to settings DB */
export async function setFlavor(flavor: CatppuccinFlavor): Promise<void> {
currentFlavor = flavor;
applyCssVariables(flavor);
try {
await setSetting('theme', flavor);
} catch (e) {
console.error('Failed to persist theme setting:', e);
}
}
/** Load saved flavor from settings DB and apply. Call once on app startup. */
export async function initTheme(): Promise<void> {
try {
const saved = await getSetting('theme');
if (saved && ['latte', 'frappe', 'macchiato', 'mocha'].includes(saved)) {
currentFlavor = saved as CatppuccinFlavor;
}
} catch {
// Fall back to default (mocha) — catppuccin.css provides Mocha defaults
}
// Always apply to sync CSS vars with current flavor
// (skip if mocha — catppuccin.css already has Mocha values)
if (currentFlavor !== 'mocha') {
applyCssVariables(currentFlavor);
}
}