Introduce workspace-aware System side panel with remote process/tmux/Docker management, terminal popup for interactive attach, capability warmup, review-hardened IPC, performance optimizations, toast action errors, and SSH channel recovery on reconnect.
* Fix#954: unify Tooltip styling + replace native selects
Replace native HTML title= tooltips and native <select> dropdowns
with the existing Radix-based Tooltip / Select components so they
share the app's rounded styling, theme tokens and i18n pipeline.
Adds a global TooltipProvider in AppWithProviders so every
descendant Tooltip works without a per-file Provider wrapper.
Scope (driven by the issue #954 examples and "全部都处理" follow-up):
- TerminalLayer toolbar: Add Terminal / Split View / SFTP / Scripts
/ Theme / AI Chat / Move panel / Close panel.
- TopTabs middle bar: quick switcher, more tabs, AI assistant, theme
toggle, settings; window-control buttons (min/max/close), tray
close and hotkey reset/disable have their native title dropped per
the user's explicit opt-out ("可以不用Tooltip,直接全局禁用
原生title 属性").
- AI panels: AIChatSidePanel session history / new chat / delete,
ConversationExport, AgentSelector, ChatInput attach / expand /
permission, ModelSelector, ProviderCard, ai-elements/tool-call.
- SFTP: SftpSidePanel header, SftpBreadcrumb, SftpFileRow,
SftpPaneToolbar, SftpTabBar, SftpTransferQueue.
- Settings: SettingsPage close, SettingsAppearanceTab theme/accent
swatches, SettingsFileAssociationsTab edit/remove, SettingsSystemTab
crash-log paths and global hotkey reset.
- Host vault: HostDetailsPanel (clear / suggestions / show-password /
key path / browse key), GroupDetailsPanel, KnownHostsManager,
ConnectionLogsManager, KeychainManager, SyncStatusButton,
CloudSyncSettings, LogView, QuickSwitcher, ScriptsSidePanel,
Terminal status bar copy-host + broadcast/focus, ZmodemProgressIndicator.
- Terminal subcomponents: HostKeywordHighlightPopover, TerminalComposeBar,
TerminalConnectionDialog, TerminalSearchBar.
- Editor: TextEditorPane (subtitle, search, wrap, promote-to-tab).
- TrayPanel session rows and port-forwarding rows.
Native <select> migrated to custom Select component:
- SerialConnectModal (data bits, stop bits, parity, flow control)
- SerialHostDetailsPanel (same four fields)
- HostDetailsPanel backspace behavior
- GroupDetailsPanel backspace behavior
- SettingsTerminalTab local shell picker
- terminal/ThemeSidePanel font weight
Hardcoded English strings extracted to i18n. New keys for both
en and zh-CN: terminal.layer.*, topTabs.*, ai.chat.* (sessionHistory,
attach, collapse, expand, enableAgent), zmodem.*, settings.shortcuts.
resetToDefault. Inline help text on SnippetsManager package-name input
removed because the same hint is already shown in a visible <p> below
the input.
Existing per-file <TooltipProvider> wrappers (SnippetsManager,
ScriptsSidePanel, SelectHostPanel, RuleCard, HostDetailsPanel proxy
section) are left in place — they nest harmlessly under the global
provider and stay self-sufficient for component tests.
Tests:
- tsc clean for changed files (pre-existing repo-wide errors
unrelated to this PR).
- All 802 tests pass (3 skipped pre-existing).
- HostDetailsPanel.proxyProfile.test and TextEditorPane.test
updated to wrap with TooltipProvider, matching the runtime
context now needed by the migrated components.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Fix#954: wrap Settings + Tray windows with TooltipProvider
Settings and the tray panel mount as separate Electron windows with
their own React root in index.tsx, so they do not inherit the global
TooltipProvider added under AppWithProviders. After the unified
Tooltip migration, any settings tab that used a Tooltip (Appearance,
Application, FileAssociations, System, Shortcuts, Terminal, AI
ProviderCard, AI ModelSelector) — and TrayPanel — threw
"Tooltip must be used within TooltipProvider" and rendered nothing.
Wrap both branches with TooltipProvider at the same level as
ToastProvider in index.tsx.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Instead of creating a new BrowserWindow on each user click, the settings window is now:
1. Pre-warmed silently 3 s after app startup (showOnLoad: false)
2. Hidden instead of destroyed when the user closes it
3. Instantly shown/focused on subsequent opens
- Replace tray click menu with a custom panel window (#/tray)
- Panel lists sessions + port forwards and allows toggling without closing
- Add tray panel IPC (hide panel, open main window)
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Defers Electron window display until the renderer signals first
meaningful paint, avoiding initial blank screens or white flashes,
especially on startup and settings windows. Implements a handshake
using a renderer-to-main process message, color-matches background
to the current theme, and falls back to a timeout in development.
Also migrates font loading to npm packages, replaces Google Fonts
usage, and adds code-splitting for dialogs and quick switcher to
improve performance. Restricts console debug output to development.
Replaces the Ghostty Web terminal backend with xterm.js, updating references, dependencies, and styles accordingly. Removes Ghostty-specific initialization, CSS, and dependencies for improved compatibility and maintainability. Updates terminal and SFTP mounting to use React lazy loading for better performance. Improves Electron window startup to avoid initial white flash. Cleans up cloud adapter dynamic imports for more efficient loading.
Updates documentation to reflect the terminal engine change.
Enables GitHub Device Flow authentication through the main process
to bypass CORS issues by introducing IPC bridge handlers and updating
the adapter to use them when available. Improves error handling and
logging for easier debugging. Wraps settings in a toast provider to
support user notifications.
Removes unnecessary whitespace to improve code readability
and maintain consistent formatting in the settings panel.
Adds dedicated settings window and improves UI sync
Implements a separate settings window in desktop mode, enabling users to open settings as a standalone dialog via Electron integration and renderer routing.
Synchronizes theme and keybinding preferences across windows using storage events for a seamless experience. Enhances Quick Switcher hotkey display accuracy, focuses terminal tab on activation, and refines UI accent color usage for consistency and accessibility.
Improves visual coherence and formatting in the settings panel, addressing theme application and component styling.
Reduces terminal scrollback for faster rendering and preloads WASM for quicker terminal startup.
Optimizes SSH connection parameters for faster failure detection and lower latency (shorter timeout, longer keepalive interval, prioritized fast ciphers and key exchange).
Decreases IPC overhead by buffering terminal data output before sending to the frontend, reducing message frequency and improving efficiency.
Reorder and normalize import statements, group icon imports, and add
missing utility imports (cn). Fix export/newline formatting and minor
type import tweaks. Add ESLint scripts to package.json and update the
lockfile.
- Updated Terminal component to use memoization for performance optimization.
- Modified onStatusChange and onCloseSession props to include sessionId for better session tracking.
- Refactored TerminalLayer to utilize stable callback references for session management functions.
- Cleaned up unnecessary whitespace in TerminalLayer and TopTabs components.
- Adjusted index.tsx to improve rendering performance by removing React.StrictMode.
- Introduced `activeTabStore` to manage active tab state with fine-grained subscriptions.
- Replaced direct prop passing of `isActive` with hooks (`useIsVaultActive`, `useIsSftpActive`) in components to determine active state.
- Memoized components (e.g., `SftpView`, `VaultView`, `TerminalLayer`, `TopTabs`) to prevent unnecessary re-renders.
- Updated various components to use `useCallback` and `useMemo` for stable references and performance improvements.
- Removed redundant state and props, simplifying the component structure.
- Disabled React.StrictMode in index.tsx for performance testing.