feat: move terminal settings, look and ssh tools into ssh-terminal plugin

This commit is contained in:
LukeGus committed 2026-09-29 02:38:37 -05:00
1 parent ffa872ebd3
commit d9bba10612
242 files changed
+25071 -7207

No files matched your search

+4 -4
View File
@@ -584,7 +584,7 @@ export async function activate(ctx: PluginContext) {
let resolvedIp = ip;
let resolvedPort = port;
let resolvedUsername = username;
let resolvedTerminalConfig: Record<string, unknown> | undefined;
let resolvedSshOptions: PluginSshHost["sshOptions"];
let resolvedJumpHosts = jumpHosts;
let resolvedScpLegacy = false;
let resolvedUseSocks5 = useSocks5;
@@ -612,8 +612,8 @@ export async function activate(ctx: PluginContext) {
certPublicKey: (resolvedHost as { certPublicKey?: string })
.certPublicKey,
};
resolvedTerminalConfig = resolvedHost.terminalConfig as unknown as
Record<string, unknown> | undefined;
resolvedSshOptions =
resolvedHost.sshOptions as PluginSshHost["sshOptions"];
resolvedScpLegacy =
(await ctx.settings.getHost<boolean>(
Number(resolvedHost.id),
@@ -728,7 +728,7 @@ export async function activate(ctx: PluginContext) {
key: resolvedCredentials.sshKey,
keyPassword: resolvedCredentials.keyPassword,
certPublicKey: resolvedCredentials.certPublicKey,
terminalConfig: resolvedTerminalConfig ?? null,
sshOptions: resolvedSshOptions ?? null,
jumpHosts: resolvedJumpHosts,
useSocks5: resolvedUseSocks5,
socks5Host: resolvedSocks5Host,
@@ -1,9 +1,10 @@
import { useCallback, useRef } from "react";
import { useCallback, useEffect, useRef } from "react";
import { createElement } from "react";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import type { FileItem } from "../host-types";
import type { LocalWalkResult } from "@termix/plugin-sdk/ui";
import { useSettings } from "@termix/plugin-sdk/frontend";
import {
cancelLocalTransfer,
createLocalTransferId,
@@ -20,8 +21,10 @@ import {
import {
UnsafeLocalNameError,
buildLocalDestination,
getTransferConcurrency,
clampTransferConcurrency,
DEFAULT_TRANSFER_CONCURRENCY,
runWithConcurrency,
takeLegacyTransferConcurrency,
joinRemotePath,
planRemoteDirectories,
remoteBaseName,
@@ -130,6 +133,27 @@ export function useLocalTransfers({
const { t } = useTranslation();
const batchCounter = useRef(0);
// "Simultaneous file transfers", the transferConcurrency user setting.
const userSettings = useSettings("user");
const concurrencyRef = useRef(DEFAULT_TRANSFER_CONCURRENCY);
concurrencyRef.current = clampTransferConcurrency(
userSettings.values.transferConcurrency ?? DEFAULT_TRANSFER_CONCURRENCY,
);
const { loaded: settingsLoaded, save: saveUserSettings } = userSettings;
useEffect(() => {
if (!settingsLoaded) return;
// A value this browser kept before 2.9.0 fills a setting still at its default.
const legacy = takeLegacyTransferConcurrency();
if (
legacy !== null &&
legacy !== concurrencyRef.current &&
concurrencyRef.current === DEFAULT_TRANSFER_CONCURRENCY
) {
concurrencyRef.current = legacy;
void saveUserSettings({ transferConcurrency: legacy }).catch(() => {});
}
}, [settingsLoaded, saveUserSettings]);
const runBatch = useCallback(
async (
direction: "upload" | "download",
@@ -316,7 +340,7 @@ export function useLocalTransfers({
let reason: string | undefined;
await runWithConcurrency(
plan.files,
getTransferConcurrency(),
concurrencyRef.current,
async (file) => {
const fileName = file.relativePath.split("/").pop()!;
const targetDir = remoteDirForRelativePath(
@@ -520,7 +544,7 @@ export function useLocalTransfers({
let reason: string | undefined;
await runWithConcurrency(
work,
getTransferConcurrency(),
concurrencyRef.current,
async ({ entry, dest }) => {
const fileName = entry.relativePath.split("/").pop()!;
const transferId = createLocalTransferId("local-download");
@@ -1,3 +1,5 @@
import type { HostSshOptions } from "@termix/plugin-sdk/frontend";
/** A host as the shell hands it to the file manager. */
export interface SSHHost {
id: number;
@@ -19,7 +21,7 @@ export interface SSHHost {
overrideCredentialUsername?: boolean;
userId?: string;
jumpHosts?: Array<{ hostId: number }>;
terminalConfig?: Record<string, unknown>;
sshOptions?: HostSshOptions | null;
notes?: string;
useSocks5?: boolean;
socks5Host?: string;
@@ -355,6 +355,7 @@ export function formatLocalModified(
// ---------------------------------------------------------------------------
// Parallel transfers
/** Where a browser kept the preference before it became a user setting. */
export const TRANSFER_CONCURRENCY_STORAGE_KEY =
"termix:file-manager:transfer-concurrency";
export const DEFAULT_TRANSFER_CONCURRENCY = 4;
@@ -366,28 +367,21 @@ export function clampTransferConcurrency(value: unknown): number {
return Math.min(MAX_TRANSFER_CONCURRENCY, Math.max(1, n));
}
/** How many files are transferred at the same time (1 = one after another). */
export function getTransferConcurrency(): number {
/**
* The value this browser kept before 2.9.0, removed as it is read so it only
* moves into the transferConcurrency user setting once. Null when none.
*/
export function takeLegacyTransferConcurrency(): number | null {
try {
const raw = localStorage.getItem(TRANSFER_CONCURRENCY_STORAGE_KEY);
return raw === null
? DEFAULT_TRANSFER_CONCURRENCY
: clampTransferConcurrency(raw);
if (raw === null) return null;
localStorage.removeItem(TRANSFER_CONCURRENCY_STORAGE_KEY);
return clampTransferConcurrency(raw);
} catch {
return DEFAULT_TRANSFER_CONCURRENCY;
return null;
}
}
export function setTransferConcurrency(value: number): number {
const clamped = clampTransferConcurrency(value);
try {
localStorage.setItem(TRANSFER_CONCURRENCY_STORAGE_KEY, String(clamped));
} catch {
// storage unavailable
}
return clamped;
}
/**
* Runs `worker` over `items` with at most `limit` in flight, preserving the
* original order of dispatch. Stops dispatching new items once `shouldStop()`