release-2.6.0 (#1085)

* fix: general bug fixes

* fix: general qol additions

* ci(deps): bump actions/setup-node in the github-actions group (#1068)

Bumps the github-actions group with 1 update: [actions/setup-node](https://github.com/actions/setup-node).


Updates `actions/setup-node` from 6 to 7
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump the dev-patch-updates group with 28 updates (#1069)

Bumps the dev-patch-updates group with 28 updates:

| Package | From | To |
| --- | --- | --- |
| [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.5.2` | `2.5.4` |
| [@codemirror/view](https://github.com/codemirror/view) | `6.43.5` | `6.43.6` |
| [@radix-ui/react-accordion](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/accordion) | `1.2.15` | `1.2.17` |
| [@radix-ui/react-alert-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/alert-dialog) | `1.1.18` | `1.1.20` |
| [@radix-ui/react-checkbox](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/checkbox) | `1.3.6` | `1.3.8` |
| [@radix-ui/react-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dialog) | `1.1.18` | `1.1.20` |
| [@radix-ui/react-dropdown-menu](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dropdown-menu) | `2.1.19` | `2.1.21` |
| [@radix-ui/react-label](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/label) | `2.1.11` | `2.1.12` |
| [@radix-ui/react-popover](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/popover) | `1.1.18` | `1.1.20` |
| [@radix-ui/react-progress](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/progress) | `1.1.11` | `1.1.13` |
| [@radix-ui/react-scroll-area](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/scroll-area) | `1.2.13` | `1.2.15` |
| [@radix-ui/react-select](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/select) | `2.3.2` | `2.3.4` |
| [@radix-ui/react-separator](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/separator) | `1.1.11` | `1.1.12` |
| [@radix-ui/react-slider](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/slider) | `1.4.2` | `1.4.4` |
| [@radix-ui/react-switch](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/switch) | `1.3.2` | `1.3.4` |
| [@radix-ui/react-tabs](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tabs) | `1.1.16` | `1.1.18` |
| [@radix-ui/react-tooltip](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tooltip) | `1.2.11` | `1.2.13` |
| [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.3.2` | `4.3.3` |
| [@uiw/codemirror-extensions-langs](https://github.com/uiwjs/react-codemirror) | `4.25.10` | `4.25.11` |
| [@uiw/codemirror-theme-github](https://github.com/uiwjs/react-codemirror) | `4.25.10` | `4.25.11` |
| [@uiw/react-codemirror](https://github.com/uiwjs/react-codemirror) | `4.25.10` | `4.25.11` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.1.9` | `4.1.10` |
| [@vitest/ui](https://github.com/vitest-dev/vitest/tree/HEAD/packages/ui) | `4.1.9` | `4.1.10` |
| [i18next](https://github.com/i18next/i18next) | `26.3.4` | `26.3.6` |
| [radix-ui](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/radix-ui) | `1.6.1` | `1.6.3` |
| [react-i18next](https://github.com/i18next/react-i18next) | `17.0.8` | `17.0.10` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.3.2` | `4.3.3` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.9` | `4.1.10` |


Updates `@biomejs/biome` from 2.5.2 to 2.5.4
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.5.4/packages/@biomejs/biome)

Updates `@codemirror/view` from 6.43.5 to 6.43.6
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/commits)

Updates `@radix-ui/react-accordion` from 1.2.15 to 1.2.17
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/accordion/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/accordion)

Updates `@radix-ui/react-alert-dialog` from 1.1.18 to 1.1.20
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/alert-dialog)

Updates `@radix-ui/react-checkbox` from 1.3.6 to 1.3.8
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/checkbox/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/checkbox)

Updates `@radix-ui/react-dialog` from 1.1.18 to 1.1.20
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dialog/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dialog)

Updates `@radix-ui/react-dropdown-menu` from 2.1.19 to 2.1.21
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dropdown-menu/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dropdown-menu)

Updates `@radix-ui/react-label` from 2.1.11 to 2.1.12
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/label/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/label)

Updates `@radix-ui/react-popover` from 1.1.18 to 1.1.20
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/popover/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/popover)

Updates `@radix-ui/react-progress` from 1.1.11 to 1.1.13
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/progress/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/progress)

Updates `@radix-ui/react-scroll-area` from 1.2.13 to 1.2.15
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/scroll-area/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/scroll-area)

Updates `@radix-ui/react-select` from 2.3.2 to 2.3.4
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/select/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/select)

Updates `@radix-ui/react-separator` from 1.1.11 to 1.1.12
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/separator/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/separator)

Updates `@radix-ui/react-slider` from 1.4.2 to 1.4.4
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/slider/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/slider)

Updates `@radix-ui/react-switch` from 1.3.2 to 1.3.4
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/switch/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/switch)

Updates `@radix-ui/react-tabs` from 1.1.16 to 1.1.18
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tabs/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tabs)

Updates `@radix-ui/react-tooltip` from 1.2.11 to 1.2.13
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tooltip/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tooltip)

Updates `@tailwindcss/vite` from 4.3.2 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/@tailwindcss-vite)

Updates `@uiw/codemirror-extensions-langs` from 4.25.10 to 4.25.11
- [Release notes](https://github.com/uiwjs/react-codemirror/releases)
- [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.25.10...v4.25.11)

Updates `@uiw/codemirror-theme-github` from 4.25.10 to 4.25.11
- [Release notes](https://github.com/uiwjs/react-codemirror/releases)
- [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.25.10...v4.25.11)

Updates `@uiw/react-codemirror` from 4.25.10 to 4.25.11
- [Release notes](https://github.com/uiwjs/react-codemirror/releases)
- [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.25.10...v4.25.11)

Updates `@vitest/coverage-v8` from 4.1.9 to 4.1.10
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/coverage-v8)

Updates `@vitest/ui` from 4.1.9 to 4.1.10
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/ui)

Updates `i18next` from 26.3.4 to 26.3.6
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v26.3.4...v26.3.6)

Updates `radix-ui` from 1.6.1 to 1.6.3
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/radix-ui/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/radix-ui)

Updates `react-i18next` from 17.0.8 to 17.0.10
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/react-i18next/compare/v17.0.8...v17.0.10)

Updates `tailwindcss` from 4.3.2 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/tailwindcss)

Updates `vitest` from 4.1.9 to 4.1.10
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.5.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@codemirror/view"
  dependency-version: 6.43.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-accordion"
  dependency-version: 1.2.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-alert-dialog"
  dependency-version: 1.1.20
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-checkbox"
  dependency-version: 1.3.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-dialog"
  dependency-version: 1.1.20
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-dropdown-menu"
  dependency-version: 2.1.21
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-label"
  dependency-version: 2.1.12
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-popover"
  dependency-version: 1.1.20
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-progress"
  dependency-version: 1.1.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-scroll-area"
  dependency-version: 1.2.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-select"
  dependency-version: 2.3.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-separator"
  dependency-version: 1.1.12
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-slider"
  dependency-version: 1.4.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-switch"
  dependency-version: 1.3.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-tabs"
  dependency-version: 1.1.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-tooltip"
  dependency-version: 1.2.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.3.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@uiw/codemirror-extensions-langs"
  dependency-version: 4.25.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@uiw/codemirror-theme-github"
  dependency-version: 4.25.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@uiw/react-codemirror"
  dependency-version: 4.25.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.1.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@vitest/ui"
  dependency-version: 4.1.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: i18next
  dependency-version: 26.3.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: radix-ui
  dependency-version: 1.6.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: react-i18next
  dependency-version: 17.0.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: tailwindcss
  dependency-version: 4.3.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: vitest
  dependency-version: 4.1.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump ws in the prod-patch-updates group (#1071)

Bumps the prod-patch-updates group with 1 update: [ws](https://github.com/websockets/ws).


Updates `ws` from 8.21.0 to 8.21.1
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.21.0...8.21.1)

---
updated-dependencies:
- dependency-name: ws
  dependency-version: 8.21.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump the major-updates group with 2 updates (#1072)

Bumps the major-updates group with 2 updates: [nanoid](https://github.com/ai/nanoid) and [typescript](https://github.com/microsoft/TypeScript).


Updates `nanoid` from 5.1.16 to 6.0.0
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/5.1.16...6.0.0)

Updates `typescript` from 6.0.3 to 7.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/commits)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: typescript
  dependency-version: 7.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix: general qol additions and new analytics/telemetrics feature

* fix: incorrect version sent to posthog

* feat: add multiplayer/shared sessions for terminal and guacd

* feat: rework Electron desktop app to run standalone-first with optional two-way sync to a remote Termix server

* Fix Guacamole tab visibility lifecycle (#1074)

Co-authored-by: default-student <default-student@github.com>
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* fix(alerts): send channel config as object payload instead of JSON string (#1075)

* fix tmux-monitor tailscale issue (#1076)

* Initial plan

* fix(tmux-monitor): explicitly handle tailscale auth in PanePreview hostConfig

For Tailscale-auth hosts the pane-preview attach path was building the
Terminal hostConfig with only the generic spread of host fields.  This
could omit or mismap auth-critical details and trigger a plain TCP/SSH
reachability path that doesn't work with Tailscale-only SSH endpoints.

The fix branches on `host.authType === "tailscale"` and:
- Carries `authType: "tailscale"` explicitly so the backend always selects
  the Tailscale-aware PTY path regardless of how the host object evolves.
- Derives `port` from `host.sshPort ?? host.port` so Tailscale SSH
  endpoints on a non-default SSH port are reached correctly.
- Leaves all non-tailscale auth types on the unchanged code path.

Reattach (bumping instanceId + attachNonce) continues to work because
terminalHostConfig is recomputed on every render with the latest
instanceIdRef.current value.

* refactor(tmux-monitor): simplify tailscale port logic with extracted variable

Address code review feedback: extract resolvedPort into a local variable
to avoid the duplicated `host.sshPort ?? host.port` expression that was
assigned to both `port` and `sshPort`.  Restructure as an if/else block
instead of an IIFE for readability.

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* chore: run prettier

* chore: update beta release text

* fix: cant update credential of an RDP host

* feat: add custom key shortcuts

* feat: add support for MFA over SSH

* fix: Invalid websocket frame causing code 10006 crash triggering restart loop

* fix(net): correct SSRF blocklist false-positive blocking all outbound IPv4 (#1079)

* fix: correct IPv4-mapped-IPv6 blocklist entry blocking all outbound IPv4

::ffff:0:0/96 in the IPv6 blocklist matches every IPv4 address once
mapped, since Node's BlockList compares addresses in their mapped form
internally regardless of the declared family. This caused
safeOutboundFetch to reject all IPv4-resolved destinations as private,
breaking outbound requests (e.g. ntfy/webhook notifications) whenever
DNS resolved to IPv4. Replaced with individual mapped ranges mirroring
the existing IPv4 blocklist.

* test: cover isBlockedAddress and link the Node BlockList citation

Exports isBlockedAddress so its family-crossing behavior around
IPv4-mapped-IPv6 addresses can actually be asserted, instead of relying
on manual container debugging to notice a regression. Also swaps the
prior "Node's BlockList compares addresses in mapped form" comment for
one citing the documented example in the Node docs
(https://nodejs.org/api/net.html#class-netblocklist), since that
behavior isn't otherwise obvious from the addSubnet/check call sites.

Related: Termix-SSH/Support#1024

* refactor: derive IPv6 mirror from IPv4 list, split DNS error messages

Two follow-ups from review:

- The IPv6 blocklist previously hand-duplicated each IPv4 range as its
  IPv4-mapped-IPv6 equivalent. Nothing enforced the two stayed in sync,
  which is exactly how the original bug (a mismatched ::ffff:0:0/96
  entry blocking all IPv4) was introduced in the first place. Now
  derived from a single blockedIpv4Ranges list in one loop.

- The connect.lookup hook threw the same "Private destinations are not
  allowed" for both an empty DNS result and an actually-blocked address.
  An empty result is a resolution failure, not a privacy decision, and
  conflating the two is the same kind of opaque-error problem that made
  this bug slow to diagnose in production. Split into distinct messages.

Also extracted the lookup hook itself (createDnsLookupHook) so it can be
unit-tested against a fake resolver directly, instead of only through a
real fetch()/Agent call — the bug lived entirely in this callback, and
undici wraps any error thrown here as a generic "fetch failed" TypeError,
which is why isolating it matters for testability.

---------

Co-authored-by: brennanneoh <497569+brennanneoh@users.noreply.github.com>

* fix(ssh): do not offer chacha20-poly1305 without the native ssh2 binding (#1081)

The availability probe treated a working OpenSSL "chacha20" cipher as proof
that chacha20-poly1305@openssh.com is usable. It is not: ssh2 pure-JS
chacha20-poly1305 corrupts the transport, so the peer aborts the KEX
("incomplete message [preauth]") and the connection times out. Easy to hit
on jump-host connections whose target sshd negotiates chacha20-poly1305
first.

Only trust the native binding (sshcrypto.node); otherwise leave the cipher
disabled so filterCiphers() drops it and AES-GCM is negotiated instead.

Co-authored-by: XtraLarge <>

* fix: add Swiss German server layout (#1078)

* chore: update release notes

* feat: continue improving desktop app 2-way sync with logic fixes and a migration dialog

* fix: dekstop app showing auth form without syncing

* feat: create desktop auto sessions for existing setups

* feat: add electron backend killing

* fix: electron login and session related bugs and updated readme for v2.6.0

* chore: finalize release notes

* fix: click to expand hosts including extra bottom margin

* fix: desktop auth modal failing to log users in

* fix: desktop app failing to sync

* fix: reverse proxy causing sync error

* chore: lint, format, and bump version to 2.6.0

* chore: sync Crowdin translations for 2.6.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: L.H. <117188168+default-student@users.noreply.github.com>
Co-authored-by: default-student <default-student@github.com>
Co-authored-by: Brad Baker <xyzulu@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Brennan Neoh <brennanneoh@users.noreply.github.com>
Co-authored-by: brennanneoh <497569+brennanneoh@users.noreply.github.com>
Co-authored-by: XtraLarge <eMail@WilliWerres.de>
Co-authored-by: ZacharyZcR <zacharyzcr1984@gmail.com>
This commit is contained in:
Luke Gustafson
2026-07-26 18:47:27 -05:00
committed by GitHub
co-authored by XtraLarge dependabot[bot] L.H. default-student Brad Baker copilot-swe-agent[bot] Copilot Autofix powered by AI Brennan Neoh brennanneoh XtraLarge ZacharyZcR
parent cf3e2cb499
commit 1a26628a48
232 changed files with 50585 additions and 32016 deletions
+216 -3
View File
@@ -389,6 +389,45 @@
"noSavedServers": "Žádné uložené servery",
"removeServer": "Odstranit"
},
"migrationNotice": {
"title": "Termix Desktop nyní běží samostatně",
"body1": "Tato aplikace se dříve připojovala přímo k vašemu serveru Termix. Byla přepracována tak, aby běžela plně samostatně a lokálně ukládala hostitele a přihlašovací údaje, takže fungovala i offline. Obousměrná synchronizace se samostatně hostovaným serverem Termix je nyní volitelná.",
"body2": "Vaši stávající hostitelé a přihlašovací údaje jsou stále na {{url}}. Zapněte vzdálenou synchronizaci a znovu se připojte k danému serveru, abyste je obnovili a udrželi obojí synchronizované i v budoucnu.",
"dismiss": "Teď ne",
"setUpSync": "Nastavení vzdálené synchronizace"
},
"remoteSync": {
"title": "Vzdálená synchronizace",
"description": "Volitelně můžete tuto desktopovou aplikaci připojit k serveru Termix hostovanému na vlastním serveru a synchronizovat hostitele, přihlašovací údaje a úryvky kódu napříč zařízeními. Aplikace vždy funguje plně offline, ať už se připojíte, nebo ne.",
"notConnected": "Nepřipojeno",
"connected": "Připojeno",
"connectedTo": "Připojeno k {{url}}",
"lastSynced": "Naposledy synchronizováno {{time}}",
"neverSynced": "Nikdy nesynchronizováno",
"syncError": "Chyba synchronizace: {{message}}",
"needsReauth": "Platnost přihlášení vypršela",
"connectButton": "Připojení k serveru",
"disconnectButton": "Odpojit",
"syncNowButton": "Synchronizovat nyní",
"syncing": "Synchronizace...",
"serverUrl": "URL serveru",
"enterServerUrl": "Zadejte prosím URL adresu serveru",
"mustIncludeProtocol": "URL serveru musí začínat http:// nebo https://",
"connectionTestFailed": "Na dané URL adrese se nepodařilo spojit se se serverem Termix.",
"allowInvalidCertificate": "Povolit neplatný certifikát",
"allowInvalidCertificateDesc": "Používejte pouze pro důvěryhodné servery s vlastním hostováním a certifikáty s vlastním podpisem nebo certifikáty IP adresy.",
"savedServers": "Uložené servery",
"removeServer": "Odstranit",
"continueButton": "Pokračovat",
"cancelButton": "Zrušit",
"signInTitle": "Přihlaste se do {{url}}",
"originTitle": "Původ připojení",
"originDescription": "Ve výchozím nastavení vyberte, odkud SSH připojení pocházejí. Toto nastavení lze u jednotlivých hostitelů přepsat.",
"originLocal": "Toto zařízení (lokální síť)",
"originRemote": "Vzdálený server",
"bannerReconnect": "Znovu se připojte",
"bannerMessage": "Vzdálená synchronizace vyžaduje opětovné ověření"
},
"versionCheck": {
"error": "Chyba kontroly verze",
"checkFailed": "Nepodařilo se zkontrolovat aktualizace",
@@ -602,6 +641,7 @@
"overrideCredentialUsername": "Přepsat uživatelské jméno pro přihlašovací údaje",
"overrideCredentialUsernameDesc": "Použijte výše uvedené uživatelské jméno místo uživatelského jména z přihlašovacích údajů.",
"oidcUsernameHint": "Použijte $oidc.preferred_username jako náhradu za vaše přihlašovací jméno OIDC.",
"tailscaleUsernameHint": "Musí se jednat o uživatele Unixu, kterému je vaše identita Tailscale udělena v SSH ACL tailnetu, nikoli nutně o uživatele root.",
"jumpHostChain": "Přejít k hostitelskému řetězci",
"portKnocking": "Klepnutí na přístav",
"addKnock": "Přidat port",
@@ -650,6 +690,11 @@
"delayAfterMs": "Zpoždění po (ms)",
"useSocks5Proxy": "Použít proxy SOCKS5",
"useSocks5ProxyDesc": "Směrování připojení přes proxy server",
"connectionOrigin": "Původ připojení",
"connectionOriginDesc": "Odkud pochází SSH připojení tohoto hostitele. Přepíše globální výchozí nastavení desktopové aplikace.",
"connectionOriginDefault": "Použít výchozí nastavení",
"connectionOriginLocal": "Toto zařízení (lokální síť)",
"connectionOriginRemote": "Vzdálený server",
"proxyHost": "Proxy hostitel",
"proxyPort": "Proxy port",
"proxyUsername": "Uživatelské jméno proxy serveru",
@@ -762,6 +807,14 @@
"customThemeBrightCyan": "Jasně azurová",
"customThemeBrightWhite": "Jasně bílá",
"customThemeResetTooltip": "Obnovit na výchozí nastavení",
"savedThemesLabel": "Uložená témata",
"saveAsGlobalTheme": "Uložit jako globální motiv",
"saveGlobalThemeNamePrompt": "Zadejte název tohoto motivu",
"saveGlobalThemeSuccess": "Téma uloženo",
"saveGlobalThemeError": "Uložení motivu se nezdařilo",
"applyGlobalThemeTooltip": "Použít toto téma",
"deleteGlobalThemeTooltip": "Smazat toto téma",
"noSavedThemes": "Zatím žádné uložené motivy",
"syntaxHighlightingLabel": "Zvýrazňování syntaxe",
"syntaxHighlightingDesc": "Obarvení výstupu terminálu (chyby, cesty, IP adresy, časová razítka)",
"syntaxHighlightingCategories": "Zvýraznit kategorie",
@@ -791,6 +844,8 @@
"enableAutoTmuxDesc": "Automatické spuštění nebo připojení k relaci tmux",
"enableSessionLogging": "Protokolování relací",
"enableSessionLoggingDesc": "Zaznamenejte výstup terminálové relace pro pozdější kontrolu",
"allowSessionSharing": "Povolit sdílení relace",
"allowSessionSharingDesc": "Umožnit sdílení živých relací na tomto hostiteli prostřednictvím odkazu nebo s ostatními uživateli",
"enableCommandHistory": "Historie příkazů",
"enableCommandHistoryDesc": "Zaznamenávejte příkazy spouštěné v tomto terminálu pro historii a automatické dokončování",
"linkClickBehaviorLabel": "Chování při kliknutí na odkaz",
@@ -895,6 +950,7 @@
"proxmoxResultImported": "{{count}} importováno",
"proxmoxResultUpdated": "{{count}} aktualizováno",
"proxmoxResultFailed": "{{count}} selhalo",
"proxmoxResultSkippedNoIp": "{{count}} přeskočeno (nenalezena žádná IP adresa)",
"proxmoxImportComplete": "Import Proxmoxu dokončen: {{summary}}",
"proxmoxDiscoveryFailed": "Objev selhal",
"proxmoxImportFailed": "Import se nezdařil",
@@ -961,6 +1017,9 @@
"failedToSaveCredential": "Uložení přihlašovacích údajů se nezdařilo",
"credentialNameRequired": "Zadejte prosím název pro přihlašovací údaje",
"credentialAuthRequired": "Přidejte heslo, SSH klíč nebo obojí",
"createCredentialFromHostBtn": "Vytvořit pověření",
"createCredentialFromHostTitle": "Vytvořit přihlašovací údaje od hostitele",
"createCredentialFromHostDesc": "Vytvořte opakovaně použitelný a sdílený záznam o přihlašovacích údajích, který bude předvyplněn aktuálním uživatelským jménem, heslem a/nebo SSH klíčem tohoto hostitele.",
"backToHosts": "Zpět k hostitelům",
"backToCredentials": "Zpět k pověřovacím dokumentům",
"pinned": "Připnuto",
@@ -1000,6 +1059,9 @@
"folderNestingHint": "Pomocí kláves / oddělte úrovně a vytvořte vnořené složky.",
"folderColor": "Barva",
"folderIcon": "Ikona",
"folderCredential": "Pověření",
"folderCredentialNone": "Nebyly přiřazeny žádné pověření",
"folderCredentialHint": "Hostitelé v této složce, kteří používají ověřování „Uložené přihlašovací údaje“, aniž by měli vybrány vlastní přihlašovací údaje, zdědí tento.",
"folderPreview": "Náhled",
"folderNameFallback": "Nepojmenovaná složka",
"createFolderButton": "Vytvořit složku",
@@ -1181,6 +1243,10 @@
"filterTagsGroup": "Štítky",
"shareHost": "Sdílení hostitele",
"shareHostTitle": "Sdílet: {{name}}",
"shareFolder": "Sdílet složku",
"shareFolderTitle": "Sdílená složka: {{name}}",
"folderSharedSuccessfully": "Sdílených {{count}} hostitelů ve složce",
"failedToShareFolder": "Sdílení složky se nezdařilo",
"sharing": {
"loadError": "Nepodařilo se načíst data sdílení. Zkuste to prosím znovu.",
"shareWithSection": "Sdílet s",
@@ -1221,6 +1287,7 @@
"shareWithCount": "Sdílet ({{count}})",
"currentAccess": "Aktuální přístup",
"noAccessEntries": "Tento hostitel ještě nebyl sdílen",
"folderShareSummary": "Sdílené {{shared}} z {{total}} hostitelů v této složce",
"grantedBy": "Uděleno",
"expires": "Platnost vyprší",
"expired": "Platnost vypršela",
@@ -1242,6 +1309,8 @@
"authMethod": "Metoda ověřování",
"authTypeDirect": "Řídit",
"authTypeCredential": "Pověření",
"authTypeNone": "Žádný",
"authTypeNoneDesc": "Nejsou uloženy žádné přihlašovací údaje. Při každém připojení budete vyzváni k zadání uživatelského jména a hesla; tyto údaje se neukládají.",
"selectCredential": "Vyberte pověření...",
"connectionSettings": "Nastavení připojení",
"displaySettings": "Nastavení displeje",
@@ -1259,6 +1328,7 @@
"rdpPort": "RDP port",
"username": "Uživatelské jméno",
"password": "Heslo",
"passwordSaved": "Heslo uloženo, zadejte heslo pro změnu",
"domain": "Doména",
"securityMode": "Bezpečnostní režim",
"colorDepth": "Barevná hloubka",
@@ -1424,7 +1494,60 @@
"expiresIn": "Platnost vyprší za {{duration}}",
"search": "Hledat spojení...",
"noSearchResults": "Vašemu vyhledávání neodpovídají žádná spojení",
"rename": "Přejmenovat relaci"
"rename": "Přejmenovat relaci",
"sectionSharedWithMe": "Sdíleno se mnou",
"sharedBy": "Sdíleno uživatelem {{username}}",
"join": "Připojit se",
"sharedSessionLabel": "{{hostName}} (sdílené)"
},
"sessionSharing": {
"guestView": {
"loading": "Připojování ke sdílené relaci...",
"linkInvalid": "Tento odkaz pro sdílení je neplatný, jeho platnost vypršela nebo byl zrušen.",
"rateLimited": "Příliš mnoho pokusů, zkuste to prosím znovu brzy",
"sessionEnded": "Tato relace skončila",
"readOnlyBadge": "Pouze zobrazení"
},
"modalTitle": "Sdílení relace",
"shareButton": "Podíl",
"notReadyToShare": "Relace ještě není připravena ke sdílení",
"modeTab": {
"link": "Odkaz",
"user": "Uživatel"
},
"linkModeDescription": "Připojit se může kdokoli s tímto odkazem, účet není potřeba.",
"userModeDescription": "Sdílejte s konkrétním uživatelem, který již má k tomuto hostiteli přístup. Pokud ještě nemá přístup, nejprve s ním hostitele sdílejte nebo použijte odkaz. Po sdílení se relace zobrazí na jeho kartě Připojení.",
"permissionLevel": {
"label": "Úroveň oprávnění",
"readOnly": "Pouze pro čtení",
"readOnlyDescription": "Může sledovat relaci živě, ale nemůže psát ani interagovat.",
"readWrite": "Čtení a zápis",
"readWriteDescription": "Může psát a interagovat s relací stejně jako její vlastník."
},
"expiryLabel": "Platnost vypršení platnosti odkazu",
"createLinkButton": "Vytvořit odkaz",
"createShareButton": "Sdílet s uživatelem",
"searchUsersPlaceholder": "Hledat uživatele...",
"noUsersFound": "Nenaleženi žádní uživatelé",
"linkCreated": "Odkaz pro sdílení vytvořen",
"linkCopied": "Odkaz zkopírován do schránky",
"copyLink": "Kopírovat odkaz",
"shareCreated": "Relace sdílena. Zobrazí se na jejich kartě Připojení.",
"shareFailed": "Vytvoření sdílené položky se nezdařilo",
"userLacksHostAccess": "Tento uživatel zatím nemá přístup k tomuto hostiteli. Nejprve s ním hostitele sdílejte nebo použijte odkaz.",
"activeShares": "Aktivní akcie",
"noActiveShares": "Pro tuto relaci nejsou žádné aktivní sdílení",
"revoke": "Zrušit",
"revokeConfirmTitle": "Zrušit toto sdílení?",
"revokeConfirmDescription": "Každý, kdo tuto sdílenou složku používá, okamžitě ztratí přístup.",
"revoked": "Podíl zrušen",
"revokeFailed": "Zrušení sdílení se nezdařilo",
"joinCount": "{{count}} připojit se",
"joinCount_other": "{{count}} se připojí",
"expiresAt": "Platnost vyprší {{date}}",
"linkShareBadge": "Odkaz",
"userShareBadge": "Uživatel: {{username}}",
"loadSharesFailed": "Nepodařilo se načíst aktivní sdílení"
},
"guacamole": {
"connecting": "Připojování k relaci {{type}}...",
@@ -1436,6 +1559,9 @@
"reconnect": "Znovu se připojte",
"retry": "Zkusit znovu",
"guacdUnavailable": "Služba vzdálené plochy (guacd) není k dispozici. Ujistěte se prosím, že je guacd spuštěná, přístupná a správně nakonfigurovaná v nastavení administrátora.",
"credentialPromptTitle": "Zadejte přihlašovací údaje RDP",
"credentialPromptDescription": "Tento hostitel je nastaven tak, aby při připojení vyžadoval přihlašovací údaje. Tyto přihlašovací údaje se používají pouze pro tuto relaci a neukládají se.",
"connect": "Připojit",
"ctrlAltDel": "Ctrl+Alt+Del",
"toolbar": {
"ctrlAltDel": "Ctrl+Alt+Del",
@@ -1461,7 +1587,9 @@
"reconnect": "Znovu připojit relaci",
"collapse": "Sbalit panel nástrojů",
"expand": "Rozbalit panel nástrojů",
"dragHandle": "Přetažením změníte pozici"
"dragHandle": "Přetažením změníte pozici",
"switchToTrackpad": "Přepnout do režimu trackpadu (tažením přesunete kurzor, klepnutím kliknete)",
"switchToTouch": "Přepnout do dotykového režimu (klepněte přímo na místo, kam chcete kliknout)"
}
},
"terminal": {
@@ -1508,6 +1636,11 @@
"totpRequired": "Vyžadováno dvoufaktorové ověřování",
"totpCodeLabel": "Ověřovací kód",
"totpVerify": "Ověřit",
"mfaPromptRequired": "Vyžadováno ověření",
"mfaPushRequired": "Vyžadováno ověřování push transakcí",
"mfaMenuPlaceholder": "Zadejte svou odpověď",
"mfaWaitingApproval": "Čekání na schválení na vašem zařízení...",
"mfaSendRequest": "Odeslat požadavek",
"warpgateAuthRequired": "Vyžadováno ověřování Warpgate",
"warpgateSecurityKey": "Bezpečnostní klíč",
"warpgateAuthUrl": "URL ověřování",
@@ -2277,7 +2410,8 @@
"resetCodeRateLimited": "Omezená rychlost: Příliš mnoho pokusů o ověření. Zkuste to prosím znovu později.",
"resetCodeRateLimitedWithTime": "Omezená rychlost: Příliš mnoho pokusů o ověření. Před dalším pokusem prosím počkejte {{time}} sekund.",
"authTokenSaveFailed": "Uložení ověřovacího tokenu se nezdařilo",
"failedToLoadServer": "Nepodařilo se načíst server"
"failedToLoadServer": "Nepodařilo se načíst server",
"remoteServerRequired": "Je vyžadován vzdálený server. Pro použití tohoto typu připojení se připojte ke vzdálenému serveru v Nastavení."
},
"messages": {
"registrationDisabled": "Registrace nového účtu je momentálně zakázána administrátorem. Přihlaste se prosím nebo kontaktujte administrátora.",
@@ -2644,6 +2778,17 @@
"sslSaveFailed": "Nepodařilo se uložit nastavení SSL",
"sslRequiresDomain": "Doména a e-mail jsou povinné",
"sslInfoNote": "Po vystavení certifikátu povolte SSL v proměnných prostředí (ENABLE_SSL=true) a restartujte Termix.",
"sslManualOption": "Manuál (nahrání certifikátu)",
"sslManualCert": "Certifikát (PEM)",
"sslManualCertPlaceholder": "-----ZAČÁTEK CERTIFIKÁTU-----",
"sslManualKey": "Soukromý klíč (PEM)",
"sslManualKeyPlaceholder": "-----ZAČÁTEK SOUKROMÉHO KLÍČE-----",
"sslManualDesc": "Vložte svůj stávající certifikát a soukromý klíč, včetně celého řetězce, pokud to vaše certifikační autorita vyžaduje.",
"sslManualUpload": "Nahrát a nainstalovat certifikát",
"sslManualUploadLoading": "Nahrávání certifikátu...",
"sslManualUploadSuccess": "Certifikát byl úspěšně nahrán a nainstalován.",
"sslManualUploadFailed": "Nahrávání certifikátu se nezdařilo",
"sslManualRequiresFields": "Je vyžadován certifikát a soukromý klíč",
"auditLogTotal": "{{total}} celkem záznamů",
"auditLogEmpty": "Nenalezeny žádné položky protokolu auditu",
"auditLogSuccess": "Úspěch",
@@ -2672,6 +2817,12 @@
"commandHistoryEnabled": "Historie příkazů",
"commandHistoryEnabledDesc": "Povolit záznam historie příkazů. Pokud je tato možnost zakázána, historie se neukládá bez ohledu na nastavení pro jednotlivé hostitele.",
"updateCommandHistoryFailed": "Nepodařilo se aktualizovat nastavení historie příkazů.",
"analyticsEnabled": "Sdílení anonymních statistik používání",
"analyticsEnabledDesc": "Odesílá anonymní denní počet uživatelů, hostitelů a využití funkcí, aby pomohl vylepšit Termix. Nikdy neobsahuje žádné osobní údaje ani podrobnosti o připojení.",
"updateAnalyticsFailed": "Nepodařilo se aktualizovat nastavení analytických nástrojů",
"sessionSharingGloballyEnabled": "Povolit sdílení relace",
"sessionSharingGloballyEnabledDesc": "Povolit sdílení relací živého terminálu, RDP, VNC a Telnet v rámci celé instance. Pokud je tato možnost zakázána, přepíše všechny přepínače sdílení pro jednotlivé hostitele.",
"updateSessionSharingFailed": "Nepodařilo se aktualizovat nastavení sdílení relace",
"sessionTimeout": "Časový limit relace",
"hours": "hodiny",
"sessionTimeoutRange": "Min. 1h · Max. 720h",
@@ -3119,6 +3270,47 @@
"executionSuccess": "Úspěch",
"executionFailed": "Selhalo"
},
"keybindings": {
"title": "Klávesové zkratky",
"description": "Přizpůsobte si klávesové zkratky pro kopírování, vkládání a ovládání v terminálu nebo propojte klávesy pro odeslání textu nebo spuštění úryvku kódu.",
"defaultsHeading": "Vestavěné zkratky",
"customHeading": "Vlastní zkratky",
"addBinding": "Přidat zkratku",
"addBindingTitle": "Přidat zkratku",
"editBindingTitle": "Upravit zkratku",
"loading": "Načítání...",
"noCustomBindings": "Zatím žádné vlastní zkratky",
"defaultBadge": "Výchozí",
"customizedBadge": "Přizpůsobeno",
"customize": "Přizpůsobit",
"resetToDefault": "Obnovit výchozí nastavení",
"resetAllToDefaults": "Obnovit vše na výchozí nastavení",
"close": "Blízko",
"cancel": "Zrušit",
"saveBinding": "Uložit zástupce",
"saveError": "Uložení klávesových zkratek se nezdařilo",
"pressKeysToRecord": "Kombinace kláves",
"pressKeysPlaceholder": "Klikněte a stiskněte klávesy",
"recording": "Stiskněte klávesy...",
"comboRequiredError": "Nejprve stiskněte kombinaci kláves",
"textRequiredError": "Zadejte text k odeslání",
"controlCodeRequiredError": "Zadejte jedno písmeno pro kontrolní kód",
"snippetRequiredError": "Vyberte úryvek",
"conflictWarning": "Tato kombinace je již vázána na {{combo}}. Uložením se obě spustí.",
"actionLabel": "Akce",
"actionCopy": "Kopírovat výběr",
"actionPaste": "Pasta",
"actionSendControlCode": "Odeslat signál Ctrl+písmeno",
"actionSendText": "Odeslat text",
"actionRunSnippet": "Spustit existující úryvek kódu",
"controlCodeLabel": "Dopis",
"textLabel": "Text k odeslání",
"appendEnterLabel": "Po odeslání stiskněte Enter",
"snippetLabel": "Úryvek",
"selectSnippetPlaceholder": "Vyberte úryvek",
"orphanedSnippetWarning": "úryvek nenalezen",
"clipboardPermissionNote": "V některých prohlížečích se může při prvním použití zobrazit výzva k zadání povolení ke schránce."
},
"userProfile": {
"donateTitle": "Udrž Termixe naživu",
"donateDescription": "Termix je zdarma, hostovaný na vlastních platformách a vyvíjí ho jen několik lidí ve svém volném čase. Pokud vám to ušetřilo čas nebo peníze, dar kryptoměn vám pomůže udržet ho v chodu.",
@@ -3134,6 +3326,7 @@
"sectionAppearance": "Vzhled",
"sectionSecurity": "Zabezpečení",
"sectionApiKeys": "Klíče API",
"sectionData": "Data",
"sectionC2sTunnels": "Tunely C2S",
"usernameLabel": "Uživatelské jméno",
"roleLabel": "Role",
@@ -3162,6 +3355,9 @@
"settingsTerminal": "Terminál",
"commandAutocomplete": "Automatické dokončování příkazů",
"commandAutocompleteDesc": "Zobrazit automatické doplňování při psaní",
"keyboardShortcuts": "Klávesové zkratky",
"keyboardShortcutsDescription": "Přizpůsobení zkratek pro kopírování, vkládání a příkazy v terminálu",
"manageShortcuts": "Spravovat",
"terminalLinkBehavior": "Kliknutí na odkaz terminálu",
"terminalLinkBehaviorDesc": "Výchozí chování při kliknutí na odkazy v terminálu",
"historyTracking": "Sledování historie",
@@ -3228,6 +3424,22 @@
"apiKeyUsageHint": "Vložte svůj klíč do",
"apiKeyUsageHintHeader": "záhlaví.",
"apiKeyPermissionsHint": "Klíče dědí oprávnění uživatele, který je vytvořil.",
"exportData": "Exportovat má data",
"exportDataDesc": "Stáhněte si zálohu svých hostitelů, přihlašovacích údajů a nastavení pro přenos do jiného zařízení",
"export": "Vývozní",
"exporting": "Export...",
"importData": "Importovat má data",
"importDataDesc": "Obnovte své hostitele, přihlašovací údaje a nastavení ze záložního souboru .sqlite",
"importDataSelected": "Vybráno: {{name}}",
"selectFile": "Vybrat soubor",
"changeFile": "Přeměna",
"import": "Importovat",
"importing": "Import...",
"exportSuccess": "Data byla úspěšně exportována",
"exportFailed": "Export dat se nezdařil",
"importSelectFile": "Nejprve prosím vyberte soubor",
"importCompleted": "Import dokončen: {{total}} položek importováno, {{skipped}} přeskočeno",
"importFailed": "Import se nezdařil: {{error}}",
"roleUser": "Uživatel",
"authMethodDual": "Duální ověřování",
"authMethodOidc": "OIDC",
@@ -3379,6 +3591,7 @@
"pageUp": "PgUp",
"pageDown": "PgDn",
"delete": "Del",
"paste": "Pasta",
"editQuickKeys": "Upravit rychlé klávesy",
"quickKeysTitle": "Rychlé klávesy",
"quickKeysDesc": "Klepnutím na × odstraníte. Podporuje až 8 znaků.",