From 536dc35258eee886bc31f68cfd8f6da831a2dc76 Mon Sep 17 00:00:00 2001
From: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Date: Sat, 24 Jan 2026 19:49:42 -0600
Subject: [PATCH] v1.11.0 (#523)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Feature request network graph
* Fixing PR442:
- Fixed:
- UI design elemets
- UI and button colors
- JSON export
- recent activity is default again
- Removed:
- Online/Offline UI labels
- left-click menu on hosts
- Added:
- small pulsing dot inside the hosts to indicate online status like in the left bar
* fix: electron build errors and skip macos job
* fix: testflight submit failure
* fix: made submit job match build type
* fix: resolve Vite build warnings for mixed static/dynamic imports (#473)
* Update Crowdin configuration file
* Update Crowdin configuration file
* fix: resolve Vite build warnings for mixed static/dynamic imports
- Convert all dynamic imports of main-axios.ts to static imports (10 files)
- Convert all dynamic imports of sonner to static imports (4 files)
- Add manual chunking configuration to vite.config.ts for better bundle splitting
- react-vendor: React and React DOM
- ui-vendor: Radix UI, lucide-react, clsx, tailwind-merge
- monaco: Monaco Editor
- codemirror: CodeMirror and related packages
- Increase chunkSizeWarningLimit to 1000kB
This resolves Vite warnings about mixed import strategies preventing
proper code-splitting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* fix: file manager incorrectly decoding/encoding when editing files (made base64/utf8 dependent)
* fix: build error on docker
* Handle enter button (#481)
* Update Crowdin configuration file
* Update Crowdin configuration file
* Update Linux Portable section with AUR link (#474)
* fix: file manager incorrectly decoding/encoding when editing files (#476)
* fix: electron build errors and skip macos job
* fix: testflight submit failure
* fix: made submit job match build type
* fix: resolve Vite build warnings for mixed static/dynamic imports (#473)
* Update Crowdin configuration file
* Update Crowdin configuration file
* fix: resolve Vite build warnings for mixed static/dynamic imports
- Convert all dynamic imports of main-axios.ts to static imports (10 files)
- Convert all dynamic imports of sonner to static imports (4 files)
- Add manual chunking configuration to vite.config.ts for better bundle splitting
- react-vendor: React and React DOM
- ui-vendor: Radix UI, lucide-react, clsx, tailwind-merge
- monaco: Monaco Editor
- codemirror: CodeMirror and related packages
- Increase chunkSizeWarningLimit to 1000kB
This resolves Vite warnings about mixed import strategies preventing
proper code-splitting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* fix: file manager incorrectly decoding/encoding when editing files (made base64/utf8 dependent)
---------
Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* fix: build error on docker (#477)
* fix: electron build errors and skip macos job
* fix: testflight submit failure
* fix: made submit job match build type
* fix: resolve Vite build warnings for mixed static/dynamic imports (#473)
* Update Crowdin configuration file
* Update Crowdin configuration file
* fix: resolve Vite build warnings for mixed static/dynamic imports
- Convert all dynamic imports of main-axios.ts to static imports (10 files)
- Convert all dynamic imports of sonner to static imports (4 files)
- Add manual chunking configuration to vite.config.ts for better bundle splitting
- react-vendor: React and React DOM
- ui-vendor: Radix UI, lucide-react, clsx, tailwind-merge
- monaco: Monaco Editor
- codemirror: CodeMirror and related packages
- Increase chunkSizeWarningLimit to 1000kB
This resolves Vite warnings about mixed import strategies preventing
proper code-splitting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* fix: file manager incorrectly decoding/encoding when editing files (made base64/utf8 dependent)
* fix: build error on docker
---------
Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* Increase max old space size for npm builds
* Increase Node.js memory limit in Dockerfile
* Remove NODE_OPTIONS from build commands in Dockerfile
* Change runner to blacksmith-4vcpu-ubuntu-2404
* fix: build error on docker
* Add handle on enter button;
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Gaylord Julien
Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
Co-authored-by: LukeGus
* fix: remove top tech
* fix: update readme
* fix: prevent long container names from overflowing card (#496)
Added min-w-0 to CardTitle to allow text truncation in flexbox.
Without this, flex items have min-width: auto which prevents
the truncate class from working properly.
Fixes #411
* fix: use SFTP readdir for file listing to support non-Linux systems (#495)
The file manager now uses SFTP readdir as the primary method for
listing files, with ls -la as a fallback. This enables compatibility
with MikroTik RouterOS and other non-Linux systems that don't have
standard shell commands.
Fixes #317
* fix: restore SSH connection timeout to 120s for 2FA authentication (#494)
The timeout was reduced from 120s to 30s in v1.10, causing 2FA login
failures. Users with keyboard-interactive authentication (TOTP/2FA)
need sufficient time to enter their verification codes before the
SSH connection times out.
Fixes #404
* feat: add Docker container healthcheck (#493)
* fix: owner should not be marked as shared when host is shared to their role (#492)
* fix: use correct MIME types for image preview (#491)
* fix: prevent session reset when updating host properties (#490)
* fix: add shell creation timeout and improve error handling (#489)
* fix: set default lineHeight to 1.0 for TUI apps compatibility (#488)
* fix: delete all related data when removing user (#487)
* fix: nginx permission denied on restricted kernels (#486)
* fix: skip existing hosts and credentials during JSON import (#485)
Added duplicate detection for SSH hosts (by ip+port+username) and
credentials (by name) during import. Existing items are now skipped
by default, or updated if replaceExisting option is enabled.
This matches the existing behavior of importDismissedAlerts.
Fixes #389
* feat: add firewall status widget for server stats (#484)
* Feature: PWA (#479)
* feat: add PWA support with offline capabilities
- Add web app manifest with icons and theme configuration
- Add service worker with cache-first strategy for static assets
- Add useServiceWorker hook for SW registration
- Add PWA meta tags and Apple-specific tags to index.html
- Update vite.config.ts for optimal asset caching
* Update package-lock.json
* New Crowdin updates (#472)
* New translations en.json (Romanian)
* New translations en.json (French)
* New translations en.json (Spanish)
* New translations en.json (Afrikaans)
* New translations en.json (Arabic)
* New translations en.json (Catalan)
* New translations en.json (Czech)
* New translations en.json (Danish)
* New translations en.json (German)
* New translations en.json (Greek)
* New translations en.json (Finnish)
* New translations en.json (Hebrew)
* New translations en.json (Hungarian)
* New translations en.json (Italian)
* New translations en.json (Japanese)
* New translations en.json (Korean)
* New translations en.json (Dutch)
* New translations en.json (Norwegian)
* New translations en.json (Polish)
* New translations en.json (Portuguese)
* New translations en.json (Russian)
* New translations en.json (Serbian (Cyrillic))
* New translations en.json (Swedish)
* New translations en.json (Turkish)
* New translations en.json (Ukrainian)
* New translations en.json (Chinese Simplified)
* New translations en.json (English)
* New translations en.json (Vietnamese)
* New translations en.json (German)
* feat: add listening ports widget for server stats (#483)
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
* feat: fix network stats merge and add openapi jsdocs comments
* feat: add workflow/config to auto generate openapi json
* feat: remove locales
* feat: support URL routes to open terminal directly (#156) (#503)
* fix: resolve merge conflict artifacts in dev-1.10.1
- Fix missing closing tags in AppView.tsx NetworkGraphView
- Fix incomplete catch blocks in server-stats.ts and db/index.ts
- Fix missing closing brace in en.json ports section
- Fix HostManagerApp.tsx import path
- Fix stats-widgets.ts type definition
- Fix schema.ts networkTopology table definition
- Add type annotations in user-data-import.ts
* feat: support URL routes to open terminal directly (#156)
- Add /terminal/{hostNameOrId} route for new format
- Keep /hosts/{id}/terminal for backward compatibility
- Smart detection: numeric IDs for ID lookup, otherwise name lookup
- Clean URL after opening to prevent duplicate on refresh
- Show toast error when host not found
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
* feat: add Ctrl+Alt key remapping for browser-blocked shortcuts (#501)
Browsers intercept Ctrl+W/T/N/Q, making them unusable in terminal.
This adds Ctrl+Alt+ as an alternative that sends Ctrl+.
- Ctrl+Alt+W → Ctrl+W (nano search, delete word)
- Ctrl+Alt+T → Ctrl+T (transpose chars)
- Ctrl+Alt+N → Ctrl+N (next line)
- Ctrl+Alt+Q → Ctrl+Q (XON flow control)
Fixes Termix-SSH/Support#407
* feat: remove locales
* New Crowdin updates (#504)
* New translations en.json (Romanian)
* New translations en.json (French)
* New translations en.json (Spanish)
* New translations en.json (Afrikaans)
* New translations en.json (Arabic)
* New translations en.json (Catalan)
* New translations en.json (Czech)
* New translations en.json (Danish)
* New translations en.json (German)
* New translations en.json (Greek)
* New translations en.json (Finnish)
* New translations en.json (Hebrew)
* New translations en.json (Hungarian)
* New translations en.json (Italian)
* New translations en.json (Japanese)
* New translations en.json (Korean)
* New translations en.json (Dutch)
* New translations en.json (Norwegian)
* New translations en.json (Polish)
* New translations en.json (Portuguese)
* New translations en.json (Russian)
* New translations en.json (Serbian (Cyrillic))
* New translations en.json (Swedish)
* New translations en.json (Turkish)
* New translations en.json (Ukrainian)
* New translations en.json (Chinese Simplified)
* New translations en.json (English)
* New translations en.json (Vietnamese)
* New translations en.json (German)
* New translations en.json (Norwegian)
* New translations en.json (Romanian)
* New translations en.json (French)
* New translations en.json (Spanish)
* New translations en.json (Arabic)
* New translations en.json (Czech)
* New translations en.json (Danish)
* New translations en.json (Greek)
* New translations en.json (Finnish)
* New translations en.json (Italian)
* New translations en.json (Japanese)
* New translations en.json (Dutch)
* New translations en.json (Norwegian)
* New translations en.json (Polish)
* New translations en.json (Portuguese)
* New translations en.json (Russian)
* New translations en.json (Swedish)
* New translations en.json (Ukrainian)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* New translations en.json (Finnish)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* feat: add option to disable update checker (#502)
* feat: add option to disable update checker
Add a new setting in User Profile > Settings to disable automatic
update checking on startup and dashboard.
- Adds 'Disable Update Check' toggle in profile settings
- Skips GitHub API calls when disabled (reduces network requests)
- Works for both web app and Electron client
Fixes Termix-SSH/Support#410
* feat: remove locales
---------
Co-authored-by: LukeGus
* New Crowdin updates (#505)
* New translations en.json (Romanian)
* New translations en.json (French)
* New translations en.json (Spanish)
* New translations en.json (Afrikaans)
* New translations en.json (Arabic)
* New translations en.json (Catalan)
* New translations en.json (Czech)
* New translations en.json (Danish)
* New translations en.json (German)
* New translations en.json (Greek)
* New translations en.json (Finnish)
* New translations en.json (Hebrew)
* New translations en.json (Hungarian)
* New translations en.json (Italian)
* New translations en.json (Japanese)
* New translations en.json (Korean)
* New translations en.json (Dutch)
* New translations en.json (Norwegian)
* New translations en.json (Polish)
* New translations en.json (Portuguese)
* New translations en.json (Russian)
* New translations en.json (Serbian (Cyrillic))
* New translations en.json (Swedish)
* New translations en.json (Turkish)
* New translations en.json (Ukrainian)
* New translations en.json (Chinese Simplified)
* New translations en.json (English)
* New translations en.json (Vietnamese)
* New translations en.json (German)
* New translations en.json (Norwegian)
* New translations en.json (Romanian)
* New translations en.json (French)
* New translations en.json (Spanish)
* New translations en.json (Arabic)
* New translations en.json (Czech)
* New translations en.json (Danish)
* New translations en.json (Greek)
* New translations en.json (Finnish)
* New translations en.json (Italian)
* New translations en.json (Japanese)
* New translations en.json (Dutch)
* New translations en.json (Norwegian)
* New translations en.json (Polish)
* New translations en.json (Portuguese)
* New translations en.json (Russian)
* New translations en.json (Swedish)
* New translations en.json (Ukrainian)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* New translations en.json (Finnish)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* New translations en.json (Bulgarian)
* New translations en.json (Indonesian)
* New translations en.json (Hindi)
* feat: add crowdin i18n
* feat: remove locales
* New Crowdin updates (#506)
* New translations en.json (Romanian)
* New translations en.json (French)
* New translations en.json (Spanish)
* New translations en.json (Afrikaans)
* New translations en.json (Arabic)
* New translations en.json (Catalan)
* New translations en.json (Czech)
* New translations en.json (Danish)
* New translations en.json (German)
* New translations en.json (Greek)
* New translations en.json (Finnish)
* New translations en.json (Hebrew)
* New translations en.json (Hungarian)
* New translations en.json (Italian)
* New translations en.json (Japanese)
* New translations en.json (Korean)
* New translations en.json (Dutch)
* New translations en.json (Norwegian)
* New translations en.json (Polish)
* New translations en.json (Portuguese)
* New translations en.json (Russian)
* New translations en.json (Serbian (Cyrillic))
* New translations en.json (Swedish)
* New translations en.json (Turkish)
* New translations en.json (Ukrainian)
* New translations en.json (Chinese Simplified)
* New translations en.json (English)
* New translations en.json (Vietnamese)
* New translations en.json (German)
* New translations en.json (Norwegian)
* New translations en.json (Romanian)
* New translations en.json (French)
* New translations en.json (Spanish)
* New translations en.json (Arabic)
* New translations en.json (Czech)
* New translations en.json (Danish)
* New translations en.json (Greek)
* New translations en.json (Finnish)
* New translations en.json (Italian)
* New translations en.json (Japanese)
* New translations en.json (Dutch)
* New translations en.json (Norwegian)
* New translations en.json (Polish)
* New translations en.json (Portuguese)
* New translations en.json (Russian)
* New translations en.json (Swedish)
* New translations en.json (Ukrainian)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* New translations en.json (Finnish)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* New translations en.json (Bulgarian)
* New translations en.json (Indonesian)
* New translations en.json (Hindi)
* New translations en.json (Romanian)
* New translations en.json (French)
* New translations en.json (Spanish)
* New translations en.json (Afrikaans)
* New translations en.json (Arabic)
* New translations en.json (Catalan)
* New translations en.json (Czech)
* New translations en.json (German)
* New translations en.json (Greek)
* New translations en.json (Finnish)
* New translations en.json (Hebrew)
* New translations en.json (Hungarian)
* New translations en.json (Italian)
* New translations en.json (Japanese)
* New translations en.json (Korean)
* New translations en.json (Dutch)
* New translations en.json (Polish)
* New translations en.json (Portuguese)
* New translations en.json (Russian)
* New translations en.json (Serbian (Cyrillic))
* New translations en.json (Turkish)
* New translations en.json (Ukrainian)
* New translations en.json (Chinese Simplified)
* New translations en.json (Chinese Traditional)
* New translations en.json (Vietnamese)
* New translations en.json (Portuguese, Brazilian)
* New translations en.json (Bulgarian)
* New translations en.json (Indonesian)
* New translations en.json (Hindi)
* New translations en.json (Bengali)
* New translations en.json (Thai)
* feat: update readme
* feat: update readme
* feat: update credential editor to use submitting system and add health monitor
* feat: added toggle for command pallete
* feat: added close button on tab dropdown
* feat: added sidebar management and improved some host manager UI/UX
* feat: re-added missing users.ts route from merge
* feat: add toggle for password reset feature in admin settings (#508)
* feat: add sudo support for file manager operations (#509)
* fix: add sudo support for listFiles and improve permission error handling (#512)
* feat: add sudo support for file manager operations
* fix: add sudo support for listFiles and improve permission error handling
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
* feat: fix sudo password dialog ui, add totp/pass reset limiting, and refreshed users screen when auth is outdated
* feat: add copy password button and fixed new line carriage issues and backend crash for auth key
* feat: added quick connection system (ad-hoc)
* Enter Key for Quick Login (#513)
* feat: added -r and -l support for tunnels
* feat: begin dashboard overhaul by splitting into cards and adding customization
* feat: improved full screen apps, overhauled dashboard, updated server stats ui, etc.
* feat: add auth.tsx suppot for fullscreen
* feat: greatly improve network graph ui/ux and migrated to use translations and theme system
* feat: update to use blacksmith
* feat: improve ui for customized tabs and hide add/edit host/credential when submiting
* feat: add warpgate support with a dialog (terminal only)
* feat: expand warpgate to docker/file manager
* fix: docker not working wtih warpgate and none auth failing for terminal
* fix: prevent owner permission loss when sharing host to own role (#514)
* Update Crowdin configuration file
* Update Crowdin configuration file
* Update Linux Portable section with AUR link (#474)
* fix: file manager incorrectly decoding/encoding when editing files (#476)
* fix: electron build errors and skip macos job
* fix: testflight submit failure
* fix: made submit job match build type
* fix: resolve Vite build warnings for mixed static/dynamic imports (#473)
* Update Crowdin configuration file
* Update Crowdin configuration file
* fix: resolve Vite build warnings for mixed static/dynamic imports
- Convert all dynamic imports of main-axios.ts to static imports (10 files)
- Convert all dynamic imports of sonner to static imports (4 files)
- Add manual chunking configuration to vite.config.ts for better bundle splitting
- react-vendor: React and React DOM
- ui-vendor: Radix UI, lucide-react, clsx, tailwind-merge
- monaco: Monaco Editor
- codemirror: CodeMirror and related packages
- Increase chunkSizeWarningLimit to 1000kB
This resolves Vite warnings about mixed import strategies preventing
proper code-splitting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* fix: file manager incorrectly decoding/encoding when editing files (made base64/utf8 dependent)
---------
Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* fix: build error on docker (#477)
* fix: electron build errors and skip macos job
* fix: testflight submit failure
* fix: made submit job match build type
* fix: resolve Vite build warnings for mixed static/dynamic imports (#473)
* Update Crowdin configuration file
* Update Crowdin configuration file
* fix: resolve Vite build warnings for mixed static/dynamic imports
- Convert all dynamic imports of main-axios.ts to static imports (10 files)
- Convert all dynamic imports of sonner to static imports (4 files)
- Add manual chunking configuration to vite.config.ts for better bundle splitting
- react-vendor: React and React DOM
- ui-vendor: Radix UI, lucide-react, clsx, tailwind-merge
- monaco: Monaco Editor
- codemirror: CodeMirror and related packages
- Increase chunkSizeWarningLimit to 1000kB
This resolves Vite warnings about mixed import strategies preventing
proper code-splitting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* fix: file manager incorrectly decoding/encoding when editing files (made base64/utf8 dependent)
* fix: build error on docker
---------
Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
* Increase max old space size for npm builds
* Increase Node.js memory limit in Dockerfile
* Remove NODE_OPTIONS from build commands in Dockerfile
* Change runner to blacksmith-4vcpu-ubuntu-2404
* fix: build error on docker
* fix: prevent owner permission loss when sharing host to own role
Fixes #391
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Gaylord Julien
Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
Co-authored-by: LukeGus
* fix: SSH key passphrase not passed for Docker and Tunnel (#521)
* perf: optimize Host Manager for large host lists
- Add ServerStatusContext for shared status polling (reduces API calls from N to 1)
- Move TooltipProvider to component root (eliminates N context instances)
- Add pagination with "Show More" button (limits initial DOM nodes per folder)
Fixes performance issues when managing ~1000 hosts with status monitoring enabled.
* fix: SSH key passphrase not passed to ssh2 for Docker and Tunnel
Database field is `key_password` but code used `keyPassword`.
Added fallback to check both field names.
Affected:
- docker.ts: Docker SSH connections with encrypted keys
- tunnel.ts: Tunnel connections with encrypted keys
---------
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
* perf: optimize Host Manager for large host lists (#520)
- Add ServerStatusContext for shared status polling (reduces API calls from N to 1)
- Move TooltipProvider to component root (eliminates N context instances)
- Add pagination with "Show More" button (limits initial DOM nodes per folder)
Fixes performance issues when managing ~1000 hosts with status monitoring enabled.
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
* fix: add missing mimeTypes definition for image preview (#518)
Fixes Termix-SSH/Support#408
* fix: prevent session reset when updating host properties (#517)
Move WebSocket cleanup logic to a separate unmount-only effect to
prevent SSH sessions from being closed when host properties are updated.
Closes Termix-SSH/Support#401
* fix: backend type error
* feat: make terminal connections more resilient, added connection log, and fixed https/proxy reconnection loop (issue #385)
* feat: improved conneciton log ui/logic
* feat: improved conneciton log ui/logic
* feat: expanded connection log to work across all components (readying for release)
* feat: update readme
* feat: update readme
* fix: build error
* fix: build error
* fix: changed ver
* chore: clean up
* chore: continue clean up
* fix: remove attempts remaining and fix electron errors and some connection log ui inconsistencies
* fix: added missing nginx routes and fixed sudo password copy with sudo password autofil field
* fix: update readme and run cleaner
* fix: update readme
* fix: update readme
* fix: update readme
* feat: update chinese readme
---------
Co-authored-by: Steven Josefs
Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI
Co-authored-by: Claude
Co-authored-by: Nunzio Marfè
Co-authored-by: Gaylord Julien
Co-authored-by: ZacharyZcR
Co-authored-by: Aditya Tawade <36890395+aditya-tawade@users.noreply.github.com>
---
.github/pull_request_template.md | 1 +
.github/workflows/docker.yml | 2 +-
.github/workflows/electron.yml | 2 +-
.github/workflows/pr-check.yml | 2 +-
.github/workflows/translate.yml | 437 ---
README-CN.md | 56 +-
README.md | 58 +-
docker/Dockerfile | 3 +
docker/nginx-https.conf | 41 +
docker/nginx.conf | 41 +
index.html | 10 +
openapi.json | 2305 ----------------
package-lock.json | 335 ++-
package.json | 9 +-
public/manifest.json | 40 +
public/sw.js | 98 +
repo-images/Image 11.png | Bin 0 -> 425324 bytes
repo-images/Image 12.png | Bin 0 -> 376926 bytes
src/backend/dashboard.ts | 262 +-
src/backend/database/database.ts | 256 ++
src/backend/database/db/index.ts | 74 +
src/backend/database/db/schema.ts | 44 +
src/backend/database/routes/alerts.ts | 90 +-
src/backend/database/routes/credentials.ts | 460 +++-
.../database/routes/network-topology.ts | 188 ++
src/backend/database/routes/rbac.ts | 383 ++-
src/backend/database/routes/snippets.ts | 374 ++-
src/backend/database/routes/ssh.ts | 1046 ++++++-
src/backend/database/routes/terminal.ts | 114 +-
src/backend/database/routes/users.ts | 1627 ++++++++---
src/backend/ssh/auth-manager.ts | 382 +++
src/backend/ssh/docker.ts | 1017 ++++++-
src/backend/ssh/file-manager.ts | 1963 ++++++++++++--
src/backend/ssh/server-stats.ts | 557 +++-
src/backend/ssh/terminal.ts | 398 ++-
src/backend/ssh/tunnel.ts | 258 +-
src/backend/ssh/widgets/firewall-collector.ts | 254 ++
src/backend/ssh/widgets/ports-collector.ts | 154 ++
src/backend/swagger.ts | 145 +
src/backend/utils/data-crypto.ts | 7 +-
src/backend/utils/field-crypto.ts | 3 +-
src/backend/utils/login-rate-limiter.ts | 140 +
src/backend/utils/permission-manager.ts | 50 +-
.../utils/shared-credential-manager.ts | 32 -
src/backend/utils/socks5-helper.ts | 14 -
src/backend/utils/user-data-import.ts | 96 +-
src/components/ui/tooltip.tsx | 4 +-
src/constants/terminal-themes.ts | 2 +-
src/hooks/use-confirmation.ts | 140 +-
src/hooks/use-service-worker.ts | 64 +
src/i18n/i18n.ts | 249 +-
src/lib/db-health-monitor.ts | 104 +
src/locales/README.md | 3 +
src/locales/ar.json | 2402 ----------------
src/locales/cs.json | 2402 ----------------
src/locales/de.json | 2402 ----------------
src/locales/el.json | 2402 ----------------
src/locales/en.json | 294 +-
src/locales/es.json | 2402 ----------------
src/locales/fr.json | 2402 ----------------
src/locales/it.json | 2402 ----------------
src/locales/ja.json | 2402 ----------------
src/locales/nb.json | 2402 ----------------
src/locales/nl.json | 2402 ----------------
src/locales/pl.json | 2402 ----------------
src/locales/pt.json | 2402 ----------------
src/locales/ro.json | 2402 ----------------
src/locales/ru.json | 2402 ----------------
src/locales/sv.json | 2402 ----------------
src/locales/translated/af.json | 2402 ++++++++++++++++
src/locales/translated/ar.json | 2402 ++++++++++++++++
src/locales/translated/bg.json | 2402 ++++++++++++++++
src/locales/{ => translated}/bn.json | 314 +--
src/locales/translated/ca.json | 2402 ++++++++++++++++
src/locales/translated/cs.json | 2402 ++++++++++++++++
src/locales/translated/da.json | 2402 ++++++++++++++++
src/locales/translated/de.json | 2402 ++++++++++++++++
src/locales/translated/el.json | 2402 ++++++++++++++++
src/locales/translated/en.json | 2406 +++++++++++++++++
src/locales/translated/es.json | 2402 ++++++++++++++++
src/locales/translated/fi.json | 2402 ++++++++++++++++
src/locales/translated/fr.json | 2402 ++++++++++++++++
src/locales/{ => translated}/he.json | 378 +--
src/locales/{ => translated}/hi.json | 332 +--
src/locales/translated/hu.json | 2402 ++++++++++++++++
src/locales/{ => translated}/id.json | 308 +--
src/locales/translated/it.json | 2402 ++++++++++++++++
src/locales/translated/ja.json | 2402 ++++++++++++++++
src/locales/{ => translated}/ko.json | 274 +-
src/locales/translated/nl.json | 2402 ++++++++++++++++
src/locales/translated/no.json | 2402 ++++++++++++++++
src/locales/translated/pl.json | 2402 ++++++++++++++++
src/locales/translated/pt.json | 2402 ++++++++++++++++
src/locales/translated/ro.json | 2402 ++++++++++++++++
src/locales/translated/ru.json | 2402 ++++++++++++++++
src/locales/translated/sr.json | 2402 ++++++++++++++++
src/locales/translated/sv.json | 2402 ++++++++++++++++
src/locales/{ => translated}/th.json | 196 +-
src/locales/{ => translated}/tr.json | 252 +-
src/locales/translated/uk.json | 2402 ++++++++++++++++
src/locales/{ => translated}/vi.json | 254 +-
src/locales/translated/zh.json | 2406 +++++++++++++++++
src/locales/uk.json | 2402 ----------------
src/locales/zh.json | 2402 ----------------
src/main.tsx | 77 +-
src/types/connection-log.ts | 40 +
src/types/index.ts | 21 +-
src/types/stats-widgets.ts | 43 +-
src/ui/contexts/ServerStatusContext.tsx | 206 ++
src/ui/desktop/DesktopApp.tsx | 153 +-
src/ui/desktop/apps/FullScreenAppWrapper.tsx | 136 +
src/ui/desktop/apps/HostManagerApp.tsx | 12 +
src/ui/desktop/apps/admin/AdminSettings.tsx | 27 +-
.../apps/admin/tabs/GeneralSettingsTab.tsx | 29 +
src/ui/desktop/apps/admin/tabs/RolesTab.tsx | 1 -
.../apps/command-palette/CommandPalette.tsx | 234 +-
src/ui/desktop/apps/dashboard/Dashboard.tsx | 564 ++--
.../apps/dashboard/cards/NetworkGraphCard.tsx | 1701 ++++++++++++
.../apps/dashboard/cards/QuickActionsCard.tsx | 141 +
.../dashboard/cards/RecentActivityCard.tsx | 97 +
.../dashboard/cards/ServerOverviewCard.tsx | 142 +
.../apps/dashboard/cards/ServerStatsCard.tsx | 80 +
.../components/DashboardSettingsDialog.tsx | 125 +
.../hooks/useDashboardPreferences.ts | 80 +
.../apps/features/docker/DockerApp.tsx | 49 +
.../apps/features/docker/DockerManager.tsx | 285 +-
.../docker/components/ContainerCard.tsx | 2 +-
.../features/file-manager/FileManager.tsx | 667 +++--
.../features/file-manager/FileManagerApp.tsx | 46 +
.../file-manager/SudoPasswordDialog.tsx | 90 +
.../file-manager/components/FileViewer.tsx | 18 +-
.../features/server-stats/ServerStats.tsx | 154 +-
.../features/server-stats/ServerStatsApp.tsx | 48 +
.../server-stats/widgets/FirewallWidget.tsx | 212 ++
.../server-stats/widgets/PortsWidget.tsx | 108 +
.../features/server-stats/widgets/index.ts | 2 +
.../apps/features/terminal/Terminal.tsx | 373 ++-
.../apps/features/terminal/TerminalApp.tsx | 49 +
.../apps/features/tunnel/TunnelApp.tsx | 48 +
.../credentials/CredentialEditor.tsx | 73 +-
.../credentials/CredentialSelector.tsx | 11 -
.../credentials/CredentialsManager.tsx | 9 -
.../apps/host-manager/hosts/HostManager.tsx | 13 +
.../host-manager/hosts/HostManagerEditor.tsx | 59 +-
.../host-manager/hosts/HostManagerViewer.tsx | 779 +++---
.../hosts/tabs/HostGeneralTab.tsx | 126 +
.../hosts/tabs/HostStatisticsTab.tsx | 5 +
.../host-manager/hosts/tabs/HostTunnelTab.tsx | 105 +-
src/ui/desktop/apps/tools/SSHToolsSidebar.tsx | 1 -
src/ui/desktop/authentication/Auth.tsx | 103 +-
src/ui/desktop/navigation/AppView.tsx | 21 +-
src/ui/desktop/navigation/TopNavbar.tsx | 28 +-
.../navigation/animations/SimpleLoader.tsx | 2 +-
.../connection-log/ConnectionLog.tsx | 193 ++
.../connection-log/ConnectionLogContext.tsx | 89 +
.../navigation/dialogs/QuickConnectDialog.tsx | 664 +++++
.../{ => dialogs}/SSHAuthDialog.tsx | 19 +-
.../navigation/{ => dialogs}/TOTPDialog.tsx | 12 +-
.../navigation/dialogs/WarpgateDialog.tsx | 124 +
src/ui/desktop/navigation/hosts/Host.tsx | 190 +-
src/ui/desktop/navigation/tabs/Tab.tsx | 100 +
.../desktop/navigation/tabs/TabDropdown.tsx | 29 +-
src/ui/desktop/user/ElectronVersionCheck.tsx | 6 +
src/ui/desktop/user/LanguageSwitcher.tsx | 9 +-
src/ui/desktop/user/UserProfile.tsx | 54 +
src/ui/main-axios.ts | 392 ++-
src/ui/mobile/apps/terminal/Terminal.tsx | 4 +-
src/ui/mobile/authentication/Auth.tsx | 66 +-
vite.config.ts | 33 +-
169 files changed, 79905 insertions(+), 47362 deletions(-)
delete mode 100644 .github/workflows/translate.yml
delete mode 100644 openapi.json
create mode 100644 public/manifest.json
create mode 100644 public/sw.js
create mode 100644 repo-images/Image 11.png
create mode 100644 repo-images/Image 12.png
create mode 100644 src/backend/database/routes/network-topology.ts
create mode 100644 src/backend/ssh/auth-manager.ts
create mode 100644 src/backend/ssh/widgets/firewall-collector.ts
create mode 100644 src/backend/ssh/widgets/ports-collector.ts
create mode 100644 src/backend/swagger.ts
create mode 100644 src/hooks/use-service-worker.ts
create mode 100644 src/lib/db-health-monitor.ts
create mode 100644 src/locales/README.md
delete mode 100644 src/locales/ar.json
delete mode 100644 src/locales/cs.json
delete mode 100644 src/locales/de.json
delete mode 100644 src/locales/el.json
delete mode 100644 src/locales/es.json
delete mode 100644 src/locales/fr.json
delete mode 100644 src/locales/it.json
delete mode 100644 src/locales/ja.json
delete mode 100644 src/locales/nb.json
delete mode 100644 src/locales/nl.json
delete mode 100644 src/locales/pl.json
delete mode 100644 src/locales/pt.json
delete mode 100644 src/locales/ro.json
delete mode 100644 src/locales/ru.json
delete mode 100644 src/locales/sv.json
create mode 100644 src/locales/translated/af.json
create mode 100644 src/locales/translated/ar.json
create mode 100644 src/locales/translated/bg.json
rename src/locales/{ => translated}/bn.json (92%)
create mode 100644 src/locales/translated/ca.json
create mode 100644 src/locales/translated/cs.json
create mode 100644 src/locales/translated/da.json
create mode 100644 src/locales/translated/de.json
create mode 100644 src/locales/translated/el.json
create mode 100644 src/locales/translated/en.json
create mode 100644 src/locales/translated/es.json
create mode 100644 src/locales/translated/fi.json
create mode 100644 src/locales/translated/fr.json
rename src/locales/{ => translated}/he.json (91%)
rename src/locales/{ => translated}/hi.json (92%)
create mode 100644 src/locales/translated/hu.json
rename src/locales/{ => translated}/id.json (92%)
create mode 100644 src/locales/translated/it.json
create mode 100644 src/locales/translated/ja.json
rename src/locales/{ => translated}/ko.json (92%)
create mode 100644 src/locales/translated/nl.json
create mode 100644 src/locales/translated/no.json
create mode 100644 src/locales/translated/pl.json
create mode 100644 src/locales/translated/pt.json
create mode 100644 src/locales/translated/ro.json
create mode 100644 src/locales/translated/ru.json
create mode 100644 src/locales/translated/sr.json
create mode 100644 src/locales/translated/sv.json
rename src/locales/{ => translated}/th.json (95%)
rename src/locales/{ => translated}/tr.json (93%)
create mode 100644 src/locales/translated/uk.json
rename src/locales/{ => translated}/vi.json (94%)
create mode 100644 src/locales/translated/zh.json
delete mode 100644 src/locales/uk.json
delete mode 100644 src/locales/zh.json
create mode 100644 src/types/connection-log.ts
create mode 100644 src/ui/contexts/ServerStatusContext.tsx
create mode 100644 src/ui/desktop/apps/FullScreenAppWrapper.tsx
create mode 100644 src/ui/desktop/apps/HostManagerApp.tsx
create mode 100644 src/ui/desktop/apps/dashboard/cards/NetworkGraphCard.tsx
create mode 100644 src/ui/desktop/apps/dashboard/cards/QuickActionsCard.tsx
create mode 100644 src/ui/desktop/apps/dashboard/cards/RecentActivityCard.tsx
create mode 100644 src/ui/desktop/apps/dashboard/cards/ServerOverviewCard.tsx
create mode 100644 src/ui/desktop/apps/dashboard/cards/ServerStatsCard.tsx
create mode 100644 src/ui/desktop/apps/dashboard/components/DashboardSettingsDialog.tsx
create mode 100644 src/ui/desktop/apps/dashboard/hooks/useDashboardPreferences.ts
create mode 100644 src/ui/desktop/apps/features/docker/DockerApp.tsx
create mode 100644 src/ui/desktop/apps/features/file-manager/FileManagerApp.tsx
create mode 100644 src/ui/desktop/apps/features/file-manager/SudoPasswordDialog.tsx
create mode 100644 src/ui/desktop/apps/features/server-stats/ServerStatsApp.tsx
create mode 100644 src/ui/desktop/apps/features/server-stats/widgets/FirewallWidget.tsx
create mode 100644 src/ui/desktop/apps/features/server-stats/widgets/PortsWidget.tsx
create mode 100644 src/ui/desktop/apps/features/terminal/TerminalApp.tsx
create mode 100644 src/ui/desktop/apps/features/tunnel/TunnelApp.tsx
create mode 100644 src/ui/desktop/navigation/connection-log/ConnectionLog.tsx
create mode 100644 src/ui/desktop/navigation/connection-log/ConnectionLogContext.tsx
create mode 100644 src/ui/desktop/navigation/dialogs/QuickConnectDialog.tsx
rename src/ui/desktop/navigation/{ => dialogs}/SSHAuthDialog.tsx (96%)
rename src/ui/desktop/navigation/{ => dialogs}/TOTPDialog.tsx (89%)
create mode 100644 src/ui/desktop/navigation/dialogs/WarpgateDialog.tsx
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 344b95ee..d0b31d4d 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -29,3 +29,4 @@ _(Optional: add before/after screenshots, GIFs, or console output)_
- [ ] Code follows project style guidelines
- [ ] Supports mobile and desktop UI/app (if applicable)
- [ ] I have read [Contributing.md](https://github.com/Termix-SSH/Termix/blob/main/CONTRIBUTING.md)
+- [ ] This is not a translation request. See [docs](https://docs.termix.site/translations)
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 34f78ea8..d5352b14 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -17,7 +17,7 @@ on:
jobs:
build:
- runs-on: blacksmith-4vcpu-ubuntu-2404
+ runs-on: blacksmith-8vcpu-ubuntu-2404
steps:
- name: Checkout repository
uses: actions/checkout@v5
diff --git a/.github/workflows/electron.yml b/.github/workflows/electron.yml
index 7c087e03..56ed3acb 100644
--- a/.github/workflows/electron.yml
+++ b/.github/workflows/electron.yml
@@ -688,7 +688,7 @@ jobs:
retention-days: 30
submit-to-flatpak:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'linux' || github.event.inputs.build_type == '')
needs: []
permissions:
diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml
index 5d0df61f..664c9538 100644
--- a/.github/workflows/pr-check.yml
+++ b/.github/workflows/pr-check.yml
@@ -6,7 +6,7 @@ on:
jobs:
lint-and-build:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Checkout code
diff --git a/.github/workflows/translate.yml b/.github/workflows/translate.yml
deleted file mode 100644
index 7c9db568..00000000
--- a/.github/workflows/translate.yml
+++ /dev/null
@@ -1,437 +0,0 @@
-name: Auto Translate
-
-on:
- workflow_dispatch:
-
-permissions:
- contents: write
- pull-requests: write
-
-jobs:
- translate-zh:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t zh --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-zh
- path: src/locales/zh.json
- continue-on-error: true
-
- translate-ru:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ru --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-ru
- path: src/locales/ru.json
- continue-on-error: true
-
- translate-pt:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t pt --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-pt
- path: src/locales/pt.json
- continue-on-error: true
-
- translate-fr:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t fr --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-fr
- path: src/locales/fr.json
- continue-on-error: true
-
- translate-es:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t es --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-es
- path: src/locales/es.json
- continue-on-error: true
-
- translate-de:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t de --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-de
- path: src/locales/de.json
- continue-on-error: true
-
- translate-hi:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t hi --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-hi
- path: src/locales/hi.json
- continue-on-error: true
-
- translate-bn:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t bn --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-bn
- path: src/locales/bn.json
- continue-on-error: true
-
- translate-ja:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ja --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-ja
- path: src/locales/ja.json
- continue-on-error: true
-
- translate-vi:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t vi --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-vi
- path: src/locales/vi.json
- continue-on-error: true
-
- translate-tr:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t tr --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-tr
- path: src/locales/tr.json
- continue-on-error: true
-
- translate-ko:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ko --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-ko
- path: src/locales/ko.json
- continue-on-error: true
-
- translate-it:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t it --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-it
- path: src/locales/it.json
- continue-on-error: true
-
- translate-he:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t he --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-he
- path: src/locales/he.json
- continue-on-error: true
-
- translate-ar:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ar --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-ar
- path: src/locales/ar.json
- continue-on-error: true
-
- translate-pl:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t pl --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-pl
- path: src/locales/pl.json
- continue-on-error: true
-
- translate-nl:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t nl --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-nl
- path: src/locales/nl.json
- continue-on-error: true
-
- translate-sv:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t sv --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-sv
- path: src/locales/sv.json
- continue-on-error: true
-
- translate-id:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t id --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-id
- path: src/locales/id.json
- continue-on-error: true
-
- translate-th:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t th --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-th
- path: src/locales/th.json
- continue-on-error: true
-
- translate-uk:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t uk --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-uk
- path: src/locales/uk.json
- continue-on-error: true
-
- translate-cs:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t cs --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-cs
- path: src/locales/cs.json
- continue-on-error: true
-
- translate-ro:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ro --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-ro
- path: src/locales/ro.json
- continue-on-error: true
-
- translate-el:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t el --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-el
- path: src/locales/el.json
- continue-on-error: true
-
- translate-nb:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: "20"
- - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t nb --maxLinesPerRequest 1
- - uses: actions/upload-artifact@v4
- with:
- name: translations-nb
- path: src/locales/nb.json
- continue-on-error: true
-
- create-pr:
- needs:
- [
- translate-zh,
- translate-ru,
- translate-pt,
- translate-fr,
- translate-es,
- translate-de,
- translate-hi,
- translate-bn,
- translate-ja,
- translate-vi,
- translate-tr,
- translate-ko,
- translate-it,
- translate-he,
- translate-ar,
- translate-pl,
- translate-nl,
- translate-sv,
- translate-id,
- translate-th,
- translate-uk,
- translate-cs,
- translate-ro,
- translate-el,
- translate-nb,
- ]
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- with:
- token: ${{ secrets.GHCR_TOKEN }}
-
- - name: Download all artifacts
- uses: actions/download-artifact@v4
- with:
- path: translations-temp
-
- - name: Move translations to src/locales
- run: |
- cp translations-temp/translations-zh/zh.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-ru/ru.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-pt/pt.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-fr/fr.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-es/es.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-de/de.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-hi/hi.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-bn/bn.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-ja/ja.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-vi/vi.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-tr/tr.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-ko/ko.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-it/it.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-he/he.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-ar/ar.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-pl/pl.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-nl/nl.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-sv/sv.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-id/id.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-th/th.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-uk/uk.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-cs/cs.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-ro/ro.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-el/el.json src/locales/ 2>/dev/null || true
- cp translations-temp/translations-nb/nb.json src/locales/ 2>/dev/null || true
- rm -rf translations-temp
-
- - name: Create Pull Request
- uses: peter-evans/create-pull-request@v6
- with:
- token: ${{ secrets.GHCR_TOKEN }}
- commit-message: "chore: auto-translate to multiple languages"
- branch: translations-update
- delete-branch: true
- title: "chore: Update translations for all languages"
diff --git a/README-CN.md b/README-CN.md
index 593c6a23..5c224730 100644
--- a/README-CN.md
+++ b/README-CN.md
@@ -16,17 +16,6 @@
2025年9月1日获得
-#### 核心技术
-
-[](#)
-[](#)
-[](#)
-[](#)
-[](#)
-[](#)
-[](#)
-[](#)
-
@@ -61,12 +50,14 @@ Termix 是一个开源、永久免费、自托管的一体化服务器管理平
- **数据导出/导入** - 导出和导入 SSH 主机、凭据和文件管理器数据
- **自动 SSL 设置** - 内置 SSL 证书生成和管理,支持 HTTPS 重定向
- **现代用户界面** - 使用 React、Tailwind CSS 和 Shadcn 构建的简洁的桌面/移动设备友好界面。可选择基于深色或浅色模式的用户界面。
-- **语言** - 内置支持约 30 种语言(通过 Google 翻译批量翻译,结果可能有所不同)
-- **平台支持** - 可作为 Web 应用程序、桌面应用程序(Windows、Linux 和 macOS)以及适用于 iOS 和 Android 的专用移动/平板电脑应用程序。
+- **语言** - 内置支持约 30 种语言(由 [Crowdin](https://docs.termix.site/translations) 管理)
+- **平台支持** - 可作为 Web 应用程序、桌面应用程序(Windows、Linux 和 macOS)、PWA 以及适用于 iOS 和 Android 的专用移动/平板电脑应用程序。
- **SSH 工具** - 创建可重用的命令片段,单击即可执行。在多个打开的终端上同时运行一个命令。
- **命令历史** - 自动完成并查看以前运行的 SSH 命令
+- **快速连接** - 无需保存连接数据即可连接到服务器
- **命令面板** - 双击左 Shift 键可快速使用键盘访问 SSH 连接
-- **SSH 功能丰富** - 支持跳板机、warpgate、基于 TOTP 的连接、SOCKS5、密码自动填充等。
+- **SSH 功能丰富** - 支持跳板机、Warpgate、基于 TOTP 的连接、SOCKS5、密码自动填充等。
+- **网络图** - 自定义您的仪表板,根据您的 SSH 连接可视化您的家庭实验室,支持状态显示
# 计划功能
@@ -76,20 +67,21 @@ Termix 是一个开源、永久免费、自托管的一体化服务器管理平
支持的设备:
-- 网站(任何平台上的任何现代浏览器,如 Chrome、Safari 和 Firefox)
+- 网站(任何平台上的任何现代浏览器,如 Chrome、Safari 和 Firefox)(包括 PWA 支持)
- Windows(x64/ia32)
- 便携版
- MSI 安装程序
- - Chocolatey 软件包管理器(即将推出)
+ - Chocolatey 软件包管理器
- Linux(x64/ia32)
- 便携版
+ - AUR
- AppImage
- Deb
- - Flatpak(即将推出)
+ - Flatpak
- macOS(x64/ia32 on v12.0+)
- - Apple App Store(即将推出)
+ - Apple App Store
- DMG
- - Homebrew(即将推出)
+ - Homebrew
- iOS/iPadOS(v15.1+)
- Apple App Store
- ISO
@@ -117,6 +109,22 @@ volumes:
driver: local
```
+# 赞助商
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 支持
如果你需要 Termix 的帮助或想要请求功能,请访问 [Issues](https://github.com/Termix-SSH/Support/issues) 页面,登录并点击 `New Issue`。
@@ -125,6 +133,8 @@ volumes:
# 展示
+[](https://www.youtube.com/watch?v=j1_I1mkhUkE)
+
@@ -147,14 +157,14 @@ volumes:
-
+
-
- 你的浏览器不支持 video 标签。
-
+
+
+
某些视频和图像可能已过时或可能无法完美展示功能。
# 许可证
diff --git a/README.md b/README.md
index d01a3aab..4fcf603e 100644
--- a/README.md
+++ b/README.md
@@ -16,17 +16,6 @@
Achieved on September 1st, 2025
-#### Top Technologies
-
-[](#)
-[](#)
-[](#)
-[](#)
-[](#)
-[](#)
-[](#)
-[](#)
-
@@ -51,24 +40,26 @@ free and self-hosted alternative to Termius available for all platforms.
# Features
- **SSH Terminal Access** - Full-featured terminal with split-screen support (up to 4 panels) with a browser-like tab system. Includes support for customizing the terminal including common terminal themes, fonts, and other components
-- **SSH Tunnel Management** - Create and manage SSH tunnels with automatic reconnection and health monitoring
-- **Remote File Manager** - Manage files directly on remote servers with support for viewing and editing code, images, audio, and video. Upload, download, rename, delete, and move files seamlessly
+- **SSH Tunnel Management** - Create and manage SSH tunnels with automatic reconnection and health monitoring and support for -l or -r connections
+- **Remote File Manager** - Manage files directly on remote servers with support for viewing and editing code, images, audio, and video. Upload, download, rename, delete, and move files seamlessly with sudo support.
- **Docker Management** - Start, stop, pause, remove containers. View container stats. Control container using docker exec terminal. It was not made to replace Portainer or Dockge but rather to simply manage your containers compared to creating them.
- **SSH Host Manager** - Save, organize, and manage your SSH connections with tags and folders, and easily save reusable login info while being able to automate the deployment of SSH keys
-- **Server Stats** - View CPU, memory, and disk usage along with network, uptime, and system information on any SSH server
+- **Server Stats** - View CPU, memory, and disk usage along with network, uptime, system information, firewall, port monitor, on most Linux based servers
- **Dashboard** - View server information at a glance on your dashboard
- **RBAC** - Create roles and share hosts across users/roles
- **User Authentication** - Secure user management with admin controls and OIDC and 2FA (TOTP) support. View active user sessions across all platforms and revoke permissions. Link your OIDC/Local accounts together.
- **Database Encryption** - Backend stored as encrypted SQLite database files. View [docs](https://docs.termix.site/security) for more.
- **Data Export/Import** - Export and import SSH hosts, credentials, and file manager data
- **Automatic SSL Setup** - Built-in SSL certificate generation and management with HTTPS redirects
-- **Modern UI** - Clean desktop/mobile-friendly interface built with React, Tailwind CSS, and Shadcn. Choose between dark or light mode based UI.
-- **Languages** - Built-in support ~30 languages (bulk translated via Google Translate, results may vary ofc)
-- **Platform Support** - Available as a web app, desktop application (Windows, Linux, and macOS), and dedicated mobile/tablet app for iOS and Android.
+- **Modern UI** - Clean desktop/mobile-friendly interface built with React, Tailwind CSS, and Shadcn. Choose between dark or light mode based UI. Use URL routes to open any connection in full-screen.
+- **Languages** - Built-in support ~30 languages (managed by [Crowdin](https://docs.termix.site/translations))
+- **Platform Support** - Available as a web app, desktop application (Windows, Linux, and macOS), PWA, and dedicated mobile/tablet app for iOS and Android.
- **SSH Tools** - Create reusable command snippets that execute with a single click. Run one command simultaneously across multiple open terminals.
- **Command History** - Auto-complete and view previously ran SSH commands
+- **Quick Connect** - Connect to a server without having to save the connection data
- **Command Palette** - Double tap left shift to quickly access SSH connections with your keyboard
-- **SSH Feature Rich** - Supports jump hosts, warpgate, TOTP based connections, SOCKS5, password autofill, etc.
+- **SSH Feature Rich** - Supports jump hosts, Warpgate, TOTP based connections, SOCKS5, password autofill, etc.
+- **Network Graph** - Customize your Dashboard to visualize your homelab based off your SSH connections with status support
# Planned Features
@@ -78,13 +69,14 @@ See [Projects](https://github.com/orgs/Termix-SSH/projects/2) for all planned fe
Supported Devices:
-- Website (any modern browser on any platform like Chrome, Safari, and Firefox)
+- Website (any modern browser on any platform like Chrome, Safari, and Firefox) (includes PWA support)
- Windows (x64/ia32)
- Portable
- MSI Installer
- Chocolatey Package Manager
- Linux (x64/ia32)
- - Portable [(AUR available)](https://aur.archlinux.org/packages/termix-bin)
+ - Portable
+ - AUR
- AppImage
- Deb
- Flatpak
@@ -120,6 +112,22 @@ volumes:
driver: local
```
+# Sponsors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# Support
If you need help or want to request a feature with Termix, visit the [Issues](https://github.com/Termix-SSH/Support/issues) page, log in, and press `New Issue`.
@@ -128,6 +136,8 @@ channel, however, response times may be longer.
# Screenshots
+[](https://www.youtube.com/watch?v=j1_I1mkhUkE)
+
@@ -150,14 +160,14 @@ channel, however, response times may be longer.
-
+
-
- Your browser does not support the video tag.
-
+
+
+
Some videos and images may be out of date or may not perfectly showcase features.
# License
diff --git a/docker/Dockerfile b/docker/Dockerfile
index ae669003..38869770 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -74,6 +74,9 @@ VOLUME ["/app/data"]
EXPOSE ${PORT} 30001 30002 30003 30004 30005 30006
+HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
+ CMD node -e "require('http').get('http://localhost:30001/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"
+
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
diff --git a/docker/nginx-https.conf b/docker/nginx-https.conf
index 7788848b..3e0b389f 100644
--- a/docker/nginx-https.conf
+++ b/docker/nginx-https.conf
@@ -1,3 +1,5 @@
+worker_processes 1;
+master_process off;
pid /app/nginx/nginx.pid;
error_log /app/nginx/logs/error.log warn;
@@ -199,6 +201,18 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
+ location /ssh/quick-connect {
+ proxy_pass http://127.0.0.1:30001;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection 'upgrade';
+ proxy_set_header Host $host;
+ proxy_cache_bypass $http_upgrade;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
location /ssh/ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
@@ -267,6 +281,15 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
+ location /ssh/file_manager/sudo-password {
+ proxy_pass http://127.0.0.1:30004;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
location /ssh/file_manager/ssh/ {
client_max_body_size 5G;
client_body_timeout 300s;
@@ -286,6 +309,15 @@ http {
proxy_buffering off;
}
+ location ~ ^/network-topology(/.*)?$ {
+ proxy_pass http://127.0.0.1:30001;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
location /health {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
@@ -335,6 +367,15 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
+ location ~ ^/dashboard/preferences(/.*)?$ {
+ proxy_pass http://127.0.0.1:30006;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
location ^~ /docker/console/ {
proxy_pass http://127.0.0.1:30008/;
proxy_http_version 1.1;
diff --git a/docker/nginx.conf b/docker/nginx.conf
index ac6b7112..5637cb6c 100644
--- a/docker/nginx.conf
+++ b/docker/nginx.conf
@@ -1,3 +1,5 @@
+worker_processes 1;
+master_process off;
pid /app/nginx/nginx.pid;
error_log /app/nginx/logs/error.log warn;
@@ -188,6 +190,18 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
+ location /ssh/quick-connect {
+ proxy_pass http://127.0.0.1:30001;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection 'upgrade';
+ proxy_set_header Host $host;
+ proxy_cache_bypass $http_upgrade;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
location /ssh/ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
@@ -256,6 +270,15 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
+ location /ssh/file_manager/sudo-password {
+ proxy_pass http://127.0.0.1:30004;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
location /ssh/file_manager/ssh/ {
client_max_body_size 5G;
client_body_timeout 300s;
@@ -275,6 +298,15 @@ http {
proxy_buffering off;
}
+ location ~ ^/network-topology(/.*)?$ {
+ proxy_pass http://127.0.0.1:30001;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
location /health {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
@@ -324,6 +356,15 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
+ location ~ ^/dashboard/preferences(/.*)?$ {
+ proxy_pass http://127.0.0.1:30006;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
location ^~ /docker/console/ {
proxy_pass http://127.0.0.1:30008/;
proxy_http_version 1.1;
diff --git a/index.html b/index.html
index b376f7cd..09531776 100644
--- a/index.html
+++ b/index.html
@@ -4,6 +4,16 @@
+
+
+
+
+
+
+
Termix