v2.0.0: 主题系统+SSH私钥解析修复+会话持久化+连接池优化+UI打磨

核心修复:
- ssh-service.ts: 新增 resolvePrivateKey(),将私钥文件路径(~/.ssh/id_rsa)解析为内容后传给 ssh2,
  解决 'Cannot parse privateKey: Unsupported key format' 错误
- useTerminalConnection.ts + sessionHelper.ts: 根据 authType 过滤字段,password/agent 认证不再传 privateKey
- sessionStore.ts: addSession() 现在先调用 sessionCreate() 持久化到 SQLite,解决恢复标签'无可用连接信息'问题
- database-service.ts: updateSession() 补充 private_key_path 字段持久化
- SessionDialog.tsx: 默认 username='root'、privateKey='~/.ssh/id_rsa'

UI/UX:
- 语义化主题系统(app-theme.ts),强制深色模式,全局无边框设计
- macOS 标题栏支持双击最大化(window:toggleMaximize IPC)
- macOS 菜单栏('OpsXShell' 应用菜单 + Settings Cmd+,)
- WelcomeView 4卡片布局,移除 Settings 按钮
- TabBar/TabItem 背景色统一(bg-dark-800/900),消除白色边框线

架构优化:
- SFTP 生命周期修复(useSFTP.ts useRef + autoConnectAttempted guard)
- 连接池竞态修复,支持快速多标签连接
- IPC 接口规范化,安全错误处理
- Vite 代码分割优化

质量: lint零错误 | tsc零错误 | build成功 | 49 tests pass
This commit is contained in:
Logan.Li committed 2026-04-22 11:15:41 +08:00
1 parent 37e65be823
commit 514d62644e
77 files changed
+2563 -931

No files matched your search

+32 -28
View File
@@ -17,16 +17,36 @@
--color-dark-700: #334155;
--color-dark-600: #475569;
/* Semantic tokens (dark default) */
--color-surface-base: #0f172a;
--color-surface-raised: #1e293b;
--color-surface-overlay: #334155;
--color-surface-inset: #475569;
--color-text-primary: #e2e8f0;
--color-text-secondary: #cbd5e1;
--color-text-muted: #94a3b8;
--color-text-faint: #64748b;
--color-text-dim: #475569;
--color-content-primary: #e2e8f0;
--color-content-secondary: #cbd5e1;
--color-content-tertiary: #94a3b8;
--color-content-inverse: #0f172a;
--color-border: #334155;
--color-border-strong: #475569;
--color-accent-blue: #3b82f6;
--color-accent-green: #10b981;
--color-accent-purple: #8b5cf6;
--color-accent-orange: #f97316;
--color-accent-red: #ef4444;
--color-feedback-success: #10b981;
--color-feedback-warning: #f59e0b;
--color-feedback-error: #ef4444;
--color-feedback-info: #3b82f6;
--color-scrollbar-track: #1e293b;
--color-scrollbar-thumb: #475569;
@@ -35,45 +55,20 @@
--color-terminal-bg: #0f172a;
}
/* ---- Light theme ---- */
:root[data-theme='light'] {
--color-dark-900: #ffffff;
--color-dark-800: #f3f4f6;
--color-dark-700: #e5e7eb;
--color-dark-600: #d1d5db;
--color-text-primary: #1f2937;
--color-text-secondary: #374151;
--color-text-muted: #6b7280;
--color-text-faint: #9ca3af;
--color-text-dim: #d1d5db;
--color-accent-blue: #2563eb;
--color-accent-green: #059669;
--color-accent-purple: #7c3aed;
--color-accent-orange: #ea580c;
--color-scrollbar-track: #f3f4f6;
--color-scrollbar-thumb: #d1d5db;
--color-scrollbar-thumb-h: #9ca3af;
--color-terminal-bg: #ffffff;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
html, body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: var(--color-dark-900);
color: var(--color-text-primary);
background-color: #0f172a !important;
color: #e2e8f0;
overflow: hidden;
}
@@ -82,6 +77,15 @@ body {
height: 100vh;
}
/* Window chrome utilities */
.drag {
-webkit-app-region: drag;
}
.no-drag {
-webkit-app-region: no-drag;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;