Frontend Development
Frontend code lives in src/ and uses React 19 + TypeScript.
Entry points and window model
The frontend entry point is src/main.tsx. It decides which app tree to load based on the ?window= query parameter in the URL:
- Main window —
AppProvider+App.tsx - Child windows —
ChildAppProvider+ChildWindowRouter
Current child-window flows include:
- settings
- new-session
- quick-command
- auto-upload
If you are changing these flows, start with:
src/main.tsxsrc/ChildWindowRouter.tsxsrc/lib/windowManager.ts
Component and directory structure
src/
├── components/ # UI components
│ ├── dialog/ # Dialog and child-window related components
│ ├── panel/ # Left/right sidebar and bottom helper panels
│ ├── terminal/ # xterm workspace and terminal-related components
│ ├── layout/ # Outer layout, title bar, activity bars
│ └── ui/ # Shared base UI components (shadcn/ui)
├── context/ # React Context providers
├── hooks/ # Custom hooks
├── i18n/ # Internationalization
├── lib/ # invoke wrapper, window manager, workspace helpers
├── pages/ # Child-window pages
├── types/ # Shared type definitions
├── App.tsx # Main application shell
└── main.tsx # Frontend entry point
State management
AppContext
src/context/AppContext.tsx is the main state container for the primary window. It manages:
- Tabs and pane trees
- Active tab and active pane
- Saved connections and group refreshes
- App settings and UI settings
- Startup restoration of the workspace
ChildAppProvider
src/context/ChildAppProvider.tsx is the lightweight provider for child windows:
- Loads and saves settings only
- Does not hold the full workspace state
- Syncs settings changes back to the main window through events
TransferContext
src/context/TransferContext.tsx listens to transfer-event and centrally manages:
- Transfer queue items
- Progress, paused, canceled, and error state
- Pause / resume / cancel / retry actions
Calling Tauri commands
Frontend code should prefer the shared wrapper in src/lib/invoke.ts rather than scattering raw @tauri-apps/api/core invoke() calls everywhere.
import { invoke } from '@/lib/invoke';
const sessionId = await invoke<string>('create_ssh_session', {
connectionId: 'uuid-here',
});
This wrapper centralizes error logging and makes future call behavior easier to change.
Listening to backend events
Many frontend features rely on Tauri events, for example:
terminal-output-{id}cwd-changed-{id}session-closed-{id}transfer-eventsessions-changedconnections-changedotp-requestcloud-sync-status-changedcloud-sync-history-changedcloud-sync-conflict
Terminal rendering, file browsing, resource monitoring, transfer queues, and the Cloud Sync status / history / conflict UI all sit on top of these events.
Workspace model
The workspace has two layers.
workspaceTabs.ts
This file manages the persisted logical workspace:
- Tabs
- Pane trees
- In-tab splits
- Serialization / restoration of
ui.open_tabs
tabWindows.ts
This file manages the live runtime terminal layout:
- Which tabs are attached to which leaf
- The active tab for each leaf
- Runtime split ratios
When editing tabs, splits, or multi-area terminal layout behavior, first decide which layer you are actually changing.
Terminal integration
src/components/terminal/XTerminal.tsx is the main xterm.js integration point. It handles:
- Search / Fit / WebLinks addons
- Shell integration and command suggestions
- Gutter rendering for line numbers and timestamps
- Action links and keyword highlighting
- Large-output protection
- Reconnect-related behavior
If you are changing terminal presentation, this is usually the first file to inspect.
Cloud Sync frontend entry points
If you are changing Cloud Sync UI flows, start with these files:
src/pages/SettingsPage.tsx— settings-tab structure, save blocking, and master-password prerequisitessrc/components/settings/SyncBackupTab.tsx— provider config, automatic strategies, manual actions, and conflict handlingsrc/components/panel/SyncBackupHistoryPanel.tsx— workspace history panel and quick conflict actionssrc/App.tsx— how the Cloud Sync panel is wired into the main workspacesrc/lib/cloudSync.ts— frontend defaults, formatting helpers, and provider validation utilities
Together these files define the full user flow through settings state, Tauri commands, and cloud-sync events.
Internationalization
User-facing UI text uses react-i18next. Locale files are in:
src/i18n/locales/zh-CN.jsonsrc/i18n/locales/en.json
Whenever you add or change visible UI text, update both locale files.
UI component conventions
The project uses shadcn/ui as its base component layer. Shared UI components live in src/components/ui/.
If you need a new reusable UI piece, prefer existing components and project style patterns over building a parallel base component system.