LukeGus
fdedca39fd
feat: convert network-topology to a full plugin (B1)
2026-09-23 07:36:39 -05:00
LukeGus
95abe24798
fix: gate second factors after SSO/LDAP behind an admin setting
2026-09-23 07:17:03 -05:00
LukeGus
f217d8db89
feat: rebuild workspaces as the reference plugin
2026-09-23 07:04:03 -05:00
LukeGus
d774df8b41
feat: add auth extension points and one ssh connect pipeline
2026-09-23 00:44:33 -05:00
LukeGus
d3c209af13
fix: mock the ai status fetch in its activate test
2026-09-22 20:20:47 -05:00
LukeGus
e88d5a52e3
feat: load plugin frontends at runtime and remove plugin ids from the shell
2026-09-22 20:15:52 -05:00
LukeGus
49f0286a14
feat: give plugins their own settings and one settings screen
2026-09-22 18:31:19 -05:00
LukeGus
cc15559ea1
feat: namespace plugin permissions and keep them valid when a plugin is off
2026-09-22 17:30:00 -05:00
LukeGus
8431570ff7
feat: serve plugin http and websockets from one mount instead of ports
2026-09-22 16:39:41 -05:00
LukeGus
c496a093ca
feat: give plugins their own tables, migrations and sync entities
2026-09-22 15:49:54 -05:00
LukeGus
5796186a1c
feat: make each plugin an npm workspace built by a termix-plugin CLI
2026-09-22 15:09:50 -05:00
LukeGus
4758016f41
feat: collapse plugin runtime to one tier behind a plugin SDK
2026-09-22 14:11:50 -05:00
LukeGus
6e058f6e9e
feat: move web endpoint into a first-party plugin
2026-09-22 12:30:35 -05:00
LukeGus
6f0dff58a3
feat: move workspaces into a first-party plugin
2026-09-22 10:45:15 -05:00
LukeGus
8742c5d381
feat: move tailscale device discovery and settings into a plugin
...
Adds plugins/tailscale/ with a devices sidebar tab, admin settings
section, and re-auth dialog. Host Metrics tailscale manager card and
SSH re-auth banner parsing stay in core.
2026-09-22 10:45:15 -05:00
LukeGus
5fbd5fb7e2
feat: move network topology into a first-party plugin
2026-09-22 10:45:15 -05:00
LukeGus
e372b0eda7
feat: remove legacy alert rules, superseded by automations
...
Alert rules already auto-migrate into automations on boot and the old
engine stands down after. Deletes the rule/firing tables, routes, UI,
and AI tools; keeps notification channels since automations still use
them. Also fixes automations' notify step, which still called the
deleted repository.
2026-09-22 10:45:12 -05:00
LukeGus
e0f14f2ecf
feat: move automations into a first-party plugin
2026-09-22 08:14:03 -05:00
LukeGus
a6f6a0439c
feat: move fleets into a first-party plugin
2026-09-21 20:44:00 -05:00
LukeGus
76b2e5739a
feat: wire remote-desktop plugin into core and rename i18n keys
...
Repoints core consumers (dispatcher, collab, session-sharing, tab
utils) at the plugin, adds isTabTypeAvailable gating for rdp/vnc/
telnet, widens hostCapability to accept an array, and renames the
guacamole i18n namespace to remoteDesktop.
2026-09-21 20:26:09 -05:00
LukeGus
c6bcfdb80d
feat: move remote desktop (RDP/VNC/Telnet) into a first-party plugin
...
Relocates guacamole backend/frontend source and tests into
plugins/remote-desktop, following the ssh-terminal/docker pattern.
2026-09-21 20:25:52 -05:00
LukeGus
d440ce9073
feat: move proxmox discovery/import/sync into a first-party plugin
2026-09-21 19:20:17 -05:00
LukeGus
9db66d5780
feat: add cross-plugin secret references gated by the provider's RBAC permission
2026-09-21 17:09:28 -05:00
LukeGus
2d6c1cdecb
feat: add a permission-gated UI action registry and action slots for plugins
...
Moves the terminal toolbar's hardwired AI button into a slot the ssh-terminal
plugin offers and the ai plugin fills, gated on ai.services.use.
2026-09-21 16:56:15 -05:00
LukeGus
225f618337
feat: add a permission-gated backend service registry for plugins
2026-09-21 16:23:00 -05:00
LukeGus
ee2d6b4697
fix: remove compiled plugin JS left behind in plugins/ after build
...
copy-bundled-plugins.cjs compiled and rewrote plugin backend TS in
place, copied it to dist/plugins, but never deleted the .js it had
just emitted next to the .ts sources. Those files shadowed the real
source for vitest/tsx and had import paths rewritten for the dist
layout, so tests failed with "Cannot find module" once a local build
had run. Affects docker, host-metrics and ai, not just this one.
2026-09-21 15:25:17 -05:00
LukeGus
504710b065
feat: ship the AI assistant as a first-party in-process plugin
...
Moves src/backend/ai and its routes into plugins/ai, mounted through a
small /ai dispatcher instead of its own port. Moves the ai-enabled and
ai-private-endpoints settings routes out of user-settings-routes.ts
into the plugin too, so it has no leftover core dependents.
2026-09-21 15:20:05 -05:00
LukeGus
c58ccbfc3f
fix: harden plugin auth and add per-request identity for ctx calls
...
Require auth on /plugin-api, gate plugin enable/grant/revoke routes
behind admin.plugins.manage, and thread the calling user through
worker ctx.hosts/ctx.ssh calls instead of always using the install
owner. Also adds the plugin permissions grant/revoke UI.
2026-09-21 14:32:59 -05:00
LukeGus
19b70430a1
feat: ship host metrics as a first-party in-process plugin
2026-09-21 11:30:46 -05:00
LukeGus
a2479c19b0
feat: ship docker as a first-party in-process plugin
...
Moves docker backend and frontend into plugins/docker/, alongside
ssh-terminal. Adds a host editor tab seam, a dashboard card registry,
and a build step to compile plugin backends into dist.
2026-09-21 09:55:37 -05:00
LukeGus
c94a453f1e
feat: ship the ssh terminal as a first-party in-process plugin
...
Adds a hardcoded process:transport-owner tier so the terminal can own its
WebSocket server and ssh2 clients, which cannot cross the worker boundary.
2026-09-21 08:28:50 -05:00
LukeGus
e040b12045
fix: update stale SFTP transfer test for single file destination paths
...
The test still asserted transferToHost was called with the destination
directory "/srv". Commit 7727fa09 (#1304 ) deliberately changed a single
file transfer to send the full destination path including the filename,
so the correct expectation is "/srv/remote-1.txt". The code was right
and the test was left behind.
2026-09-21 07:23:48 -05:00
LukeGus
4e1dec8435
feat: dispatch plugin HTTP routes and wire the runtime into startup
...
ctx.http.route now registers a real router on the /plugin-api/:pluginId
dispatcher, replacing its stub 404. A plugin never touches the Express
req/res: it gets a plain summary and returns a plain object, so sockets
and session cookies stay on this side of the boundary. Authorization and
cookie headers are not forwarded.
Plugins load last in the start-up sequence, after the server is fully
wired, and are terminated before the database on shutdown so none can
outlive it. A plugin that fails to load cannot stop the backend.
fix: correct the nginx plugin-api location regex
The pattern was ^/plugin-api/(/.*)?$, which needs a double slash and so
never matched /plugin-api/<id>/<route>. Every other block in the file
uses ^/prefix(/.*)?$. Left alone, plugin routes would work in dev and
404 only behind Docker.
2026-09-21 07:19:02 -05:00
LukeGus
4311a0e98a
feat: add plugin ctx broker with permission gate and audit
...
Every ctx call a plugin makes is checked against its granted
capabilities, performed by the main thread, then audited. A capability
must be both declared in the manifest and granted in the database, so
widening a plugin's reach always needs a new manifest the user can see,
never just a database row.
Audit attribution is set by the broker, not the plugin. The plugin
supplies only the details, so it cannot forge the actor.
fix: stop plugin workers seeing plaintext credentials in error messages
A failing ctx.ssh.connect handed the worker the raw error from deep in
the SSH stack, which embeds the connect config. The worker received, in
full:
Authentication failed for root using password <SECRET>
where <SECRET> was the host's real plaintext password. Any plugin with
ssh.exec could read it by catching the error, defeating the whole point
of the handle-based ssh API.
Errors crossing the boundary are now sanitised. Only PluginFacingError
and PluginPermissionError, both authored here, reach a plugin verbatim;
anything else becomes a generic message and the real one goes to the
log. This uses a marker class rather than matching on message text,
because matching would start leaking again the moment an upstream error
happened to contain a familiar phrase.
Covered by credential-isolation.test.ts, which plants a sentinel in
every secret-bearing field and asserts it appears in no message the
worker ever receives.
2026-09-21 07:19:01 -05:00
LukeGus
1393fa7581
feat: route internal events through a shared plugin event bus
...
Formalises three ad-hoc publish paths that already existed:
automation-events.ts, metrics/automation-bridge.ts and the
hostSessionStatus singleton, now the host.session.status topic.
Both invariants the old code relied on are preserved. Publishing stays
fire-and-forget, so a failing subscriber cannot disturb a metrics poll or
a host delete. The automations engine subscribes to the bus at scheduler
start instead of being imported ad hoc, which keeps the edge
one-directional: automations may import repositories, hosts modules must
not import automations.
2026-09-21 07:19:01 -05:00
LukeGus
0a771c9600
feat: add plugin loader with manifest validation and crash restart
...
Validates an unpacked plugin, spawns a worker_threads worker and manages
activate/deactivate/crash-restart with backoff, disabling after three
tries.
The crash counter clears only after a plugin stays up past a stability
window, not on activation. Clearing it on activation let a plugin that
activates cleanly and then dies restart forever, because every attempt
looked like the first.
loader.ts documents what the worker boundary does and does not buy you.
Node's permission model is process-wide, not per-worker, so it cannot be
enabled for plugin workers alone and is not claimed here.
2026-09-21 07:19:01 -05:00
LukeGus
9f4a2d3951
feat: add allowlisted host view for plugins
...
An allowlist rather than a list of fields to strip. A blocklist rots:
the moment a new secret-bearing column lands on SSHHost it starts
leaking silently. With an allowlist a new field stays invisible to
plugins until someone adds it here on purpose.
2026-09-21 07:19:01 -05:00
LukeGus
248698f62d
feat: add plugin worker protocol, bootstrap and plugin_storage table
...
Worker-side ctx proxy plus the message envelope it talks over, and the
per-plugin key/value table behind ctx.storage with migrations for all
three dialects. Rows cascade with the plugin so uninstalling leaves
nothing behind.
2026-09-21 07:19:01 -05:00
dependabot[bot]
a1805cb7ae
chore(deps): bump the prod-patch-updates group with 6 updates ( #1461 )
...
Bumps the prod-patch-updates group with 6 updates:
| Package | From | To |
| --- | --- | --- |
| [@tanstack/react-virtual](https://github.com/TanStack/virtual/tree/HEAD/packages/react-virtual ) | `3.14.10` | `3.14.13` |
| [compression](https://github.com/expressjs/compression ) | `1.8.1` | `1.8.2` |
| [jose](https://github.com/panva/jose ) | `6.2.9` | `6.2.12` |
| [jszip](https://github.com/Stuk/jszip ) | `3.10.1` | `3.10.2` |
| [socks](https://github.com/JoshGlazebrook/socks ) | `2.8.9` | `2.8.10` |
| [undici](https://github.com/nodejs/undici ) | `8.10.0` | `8.10.2` |
Updates `@tanstack/react-virtual` from 3.14.10 to 3.14.13
- [Release notes](https://github.com/TanStack/virtual/releases )
- [Changelog](https://github.com/TanStack/virtual/blob/main/packages/react-virtual/CHANGELOG.md )
- [Commits](https://github.com/TanStack/virtual/commits/@tanstack/react-virtual@3.14.13/packages/react-virtual )
Updates `compression` from 1.8.1 to 1.8.2
- [Release notes](https://github.com/expressjs/compression/releases )
- [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md )
- [Commits](https://github.com/expressjs/compression/compare/v1.8.1...v1.8.2 )
Updates `jose` from 6.2.9 to 6.2.12
- [Release notes](https://github.com/panva/jose/releases )
- [Changelog](https://github.com/panva/jose/blob/main/CHANGELOG.md )
- [Commits](https://github.com/panva/jose/compare/v6.2.9...v6.2.12 )
Updates `jszip` from 3.10.1 to 3.10.2
- [Changelog](https://github.com/Stuk/jszip/blob/main/CHANGES.md )
- [Commits](https://github.com/Stuk/jszip/compare/v3.10.1...v3.10.2 )
Updates `socks` from 2.8.9 to 2.8.10
- [Release notes](https://github.com/JoshGlazebrook/socks/releases )
- [Commits](https://github.com/JoshGlazebrook/socks/compare/2.8.9...2.8.10 )
Updates `undici` from 8.10.0 to 8.10.2
- [Release notes](https://github.com/nodejs/undici/releases )
- [Commits](https://github.com/nodejs/undici/compare/v8.10.0...v8.10.2 )
---
updated-dependencies:
- dependency-name: "@tanstack/react-virtual"
dependency-version: 3.14.13
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: prod-patch-updates
- dependency-name: compression
dependency-version: 1.8.2
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: prod-patch-updates
- dependency-name: jose
dependency-version: 6.2.12
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: prod-patch-updates
- dependency-name: jszip
dependency-version: 3.10.2
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: prod-patch-updates
- dependency-name: socks
dependency-version: 2.8.10
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: prod-patch-updates
- dependency-name: undici
dependency-version: 8.10.2
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>
2026-09-21 01:27:00 -05:00
dependabot[bot]
f92ad3a3f7
chore(deps-dev): bump the dev-patch-updates group with 13 updates ( #1459 )
...
Bumps the dev-patch-updates group with 13 updates:
| Package | From | To |
| --- | --- | --- |
| [@codemirror/commands](https://github.com/codemirror/commands ) | `6.11.0` | `6.11.1` |
| [@codemirror/search](https://github.com/codemirror/search ) | `6.7.1` | `6.7.2` |
| [@codemirror/view](https://github.com/codemirror/view ) | `6.43.9` | `6.43.12` |
| [@testing-library/dom](https://github.com/testing-library/dom-testing-library ) | `10.4.1` | `10.4.2` |
| [@testing-library/react](https://github.com/testing-library/react-testing-library ) | `16.3.2` | `16.3.3` |
| [@testing-library/user-event](https://github.com/testing-library/user-event ) | `14.6.5` | `14.6.7` |
| [@types/ssh2](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ssh2 ) | `1.15.5` | `1.15.6` |
| [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react ) | `6.1.0` | `6.1.1` |
| [cytoscape](https://github.com/cytoscape/cytoscape.js ) | `3.34.1` | `3.34.3` |
| [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh ) | `0.5.4` | `0.5.7` |
| [i18next](https://github.com/i18next/i18next ) | `26.4.0` | `26.4.2` |
| [prettier](https://github.com/prettier/prettier ) | `3.9.6` | `3.9.8` |
| [react-i18next](https://github.com/i18next/react-i18next ) | `17.0.12` | `17.0.14` |
Updates `@codemirror/commands` from 6.11.0 to 6.11.1
- [Changelog](https://github.com/codemirror/commands/blob/main/CHANGELOG.md )
- [Commits](https://github.com/codemirror/commands/commits )
Updates `@codemirror/search` from 6.7.1 to 6.7.2
- [Changelog](https://github.com/codemirror/search/blob/main/CHANGELOG.md )
- [Commits](https://github.com/codemirror/search/commits )
Updates `@codemirror/view` from 6.43.9 to 6.43.12
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md )
- [Commits](https://github.com/codemirror/view/commits )
Updates `@testing-library/dom` from 10.4.1 to 10.4.2
- [Release notes](https://github.com/testing-library/dom-testing-library/releases )
- [Changelog](https://github.com/testing-library/dom-testing-library/blob/main/CHANGELOG.md )
- [Commits](https://github.com/testing-library/dom-testing-library/compare/v10.4.1...v10.4.2 )
Updates `@testing-library/react` from 16.3.2 to 16.3.3
- [Release notes](https://github.com/testing-library/react-testing-library/releases )
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md )
- [Commits](https://github.com/testing-library/react-testing-library/compare/v16.3.2...v16.3.3 )
Updates `@testing-library/user-event` from 14.6.5 to 14.6.7
- [Release notes](https://github.com/testing-library/user-event/releases )
- [Changelog](https://github.com/testing-library/user-event/blob/main/CHANGELOG.md )
- [Commits](https://github.com/testing-library/user-event/compare/v14.6.5...v14.6.7 )
Updates `@types/ssh2` from 1.15.5 to 1.15.6
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases )
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ssh2 )
Updates `@vitejs/plugin-react` from 6.1.0 to 6.1.1
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases )
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md )
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.1.1/packages/plugin-react )
Updates `cytoscape` from 3.34.1 to 3.34.3
- [Release notes](https://github.com/cytoscape/cytoscape.js/releases )
- [Commits](https://github.com/cytoscape/cytoscape.js/compare/v3.34.1...v3.34.3 )
Updates `eslint-plugin-react-refresh` from 0.5.4 to 0.5.7
- [Release notes](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/releases )
- [Changelog](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/CHANGELOG.md )
- [Commits](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/compare/v0.5.4...v0.5.7 )
Updates `i18next` from 26.4.0 to 26.4.2
- [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.4.0...v26.4.2 )
Updates `prettier` from 3.9.6 to 3.9.8
- [Release notes](https://github.com/prettier/prettier/releases )
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md )
- [Commits](https://github.com/prettier/prettier/compare/3.9.6...3.9.8 )
Updates `react-i18next` from 17.0.12 to 17.0.14
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md )
- [Commits](https://github.com/i18next/react-i18next/compare/v17.0.12...v17.0.14 )
---
updated-dependencies:
- dependency-name: "@codemirror/commands"
dependency-version: 6.11.1
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: "@codemirror/search"
dependency-version: 6.7.2
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: "@codemirror/view"
dependency-version: 6.43.12
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: "@testing-library/dom"
dependency-version: 10.4.2
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: "@testing-library/react"
dependency-version: 16.3.3
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: "@testing-library/user-event"
dependency-version: 14.6.7
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: "@types/ssh2"
dependency-version: 1.15.6
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: "@vitejs/plugin-react"
dependency-version: 6.1.1
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: cytoscape
dependency-version: 3.34.3
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: eslint-plugin-react-refresh
dependency-version: 0.5.7
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: i18next
dependency-version: 26.4.2
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: prettier
dependency-version: 3.9.8
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: dev-patch-updates
- dependency-name: react-i18next
dependency-version: 17.0.14
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>
2026-09-21 01:25:56 -05:00
dependabot[bot]
ae011e6282
ci(deps): bump the github-actions group with 2 updates ( #1458 )
...
Bumps the github-actions group with 2 updates: [crowdin/github-action](https://github.com/crowdin/github-action ) and [actions/github-script](https://github.com/actions/github-script ).
Updates `crowdin/github-action` from 2 to 3
- [Release notes](https://github.com/crowdin/github-action/releases )
- [Commits](https://github.com/crowdin/github-action/compare/v2...v3 )
Updates `actions/github-script` from 7 to 9
- [Release notes](https://github.com/actions/github-script/releases )
- [Commits](https://github.com/actions/github-script/compare/v7...v9 )
---
updated-dependencies:
- dependency-name: crowdin/github-action
dependency-version: '3'
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: github-actions
- dependency-name: actions/github-script
dependency-version: '9'
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>
2026-09-21 01:25:17 -05:00
LukeGus
7f1beddccc
feat: add category and icon fields to plugin manifest schema
2026-09-20 21:06:16 -05:00
LukeGus
5a76d30637
chore: increment ver
2026-09-20 21:00:38 -05:00
LukeGus
6b56accec8
fix: host key updates not syncing, metrics 404 race on first connect
...
Host key writes never bumped updatedAt so sync never picked them up.
Also retry the first metrics fetch briefly instead of failing right away.
2026-09-20 20:24:43 -05:00
LukeGus
f694023a65
fix: Tunnel authentication with shared credentials ( #1295 )
...
https://github.com/Termix-SSH/Support/issues/1295
2026-09-20 19:46:04 -05:00
LukeGus
beb5145475
fix: node-MainThread ( #1300 )
...
https://github.com/Termix-SSH/Support/issues/1300
2026-09-20 19:12:34 -05:00
LukeGus
a9a3bbc5f4
fix: sudo password not autofilling ( #1248 )
...
https://github.com/Termix-SSH/Support/issues/1248
2026-09-20 19:06:59 -05:00
LukeGus
7727fa09fb
fix: I can't send a file on its own. ( #1304 )
...
https://github.com/Termix-SSH/Support/issues/1304
2026-09-20 19:06:54 -05:00
LukeGus
e9fd092ebd
fix: Search in side bar shows overlapping hosts when grouped by tags ( #1303 )
...
https://github.com/Termix-SSH/Support/issues/1303
2026-09-20 19:06:07 -05:00
LukeGus
afae2889cb
feat: Sidebar host click should focus existing tab instead of opening a new connection ( #1289 )
...
https://github.com/Termix-SSH/Support/issues/1289
2026-09-20 18:59:33 -05:00