fix: finish 2.9.0 plugin moves and get every check green

This commit is contained in:
LukeGus committed 2026-09-24 23:35:18 -05:00
1 parent 8c1e02af89
commit 6489b62ece
335 files changed
+29878 -17749

No files matched your search

+19 -1
View File
@@ -9,6 +9,12 @@ import type { PluginContext, PluginSshHost } from "@termix/plugin-sdk/backend";
import { getErrorMessage } from "./error-message.js";
import { setPluginSsh, pluginSsh } from "./ssh.js";
import { setPluginCtx } from "./plugin-ctx.js";
import {
flushTransferProfiles,
setTransferProfileStore,
} from "./transfer-tuning.js";
const TRANSFER_PROFILES_KEY = "transfer-profiles";
import { AuthManager } from "../../../../src/backend/utils/auth-manager.js";
import { logger } from "../../../../src/backend/utils/logger.js";
import {
@@ -113,6 +119,14 @@ export async function activate(ctx: PluginContext) {
setPluginCtx(ctx);
ctx.disposables.add(() => setPluginSsh(null));
ctx.disposables.add(() => setPluginCtx(null));
setTransferProfileStore({
read: () => ctx.kv.get(TRANSFER_PROFILES_KEY),
write: (value) => ctx.kv.set(TRANSFER_PROFILES_KEY, value),
});
ctx.disposables.add(async () => {
await flushTransferProfiles();
setTransferProfileStore(null);
});
/* eslint-disable @typescript-eslint/no-explicit-any */
// ctx.db.define hands back an untyped table object; typed at this module's
@@ -605,7 +619,11 @@ export async function activate(ctx: PluginContext) {
};
resolvedTerminalConfig = resolvedHost.terminalConfig as unknown as
Record<string, unknown> | undefined;
resolvedScpLegacy = resolvedHost.scpLegacy ?? false;
resolvedScpLegacy =
(await ctx.settings.getHost<boolean>(
Number(resolvedHost.id),
"scpLegacy",
)) === true;
if (resolvedHost.useSocks5) {
resolvedUseSocks5 = resolvedHost.useSocks5;
resolvedSocks5Host = resolvedHost.socks5Host;
@@ -1,7 +1,4 @@
// TODO(file-manager): move this to ctx.kv, see FINISH-LIST.md
import { createHash } from "node:crypto";
import { promises as fs } from "node:fs";
import path from "node:path";
export interface TransferPerformanceProfile {
throughputBps: number;
@@ -32,15 +29,32 @@ const MB = 1024 * 1024;
const PROFILE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
const MAX_PROFILES = 128;
const STORE_VERSION = 1;
const STORE_FILENAME = "adaptive-transfer-profiles.json";
const profiles = new Map<string, TransferPerformanceProfile>();
const directRoutes = new Map<string, DirectRouteProfile>();
let loadedPath: string | undefined;
/** Where the learned profiles live: ctx.kv, set on activate. */
export interface TransferProfileStore {
read: () => Promise<unknown>;
write: (value: PersistedProfiles) => Promise<void>;
}
let store: TransferProfileStore | null = null;
let loadedStore: TransferProfileStore | null = null;
let loadPromise: Promise<void> | undefined;
export function setTransferProfileStore(
next: TransferProfileStore | null,
): void {
store = next;
loadedStore = null;
loadPromise = undefined;
profiles.clear();
directRoutes.clear();
}
let persistTimer: ReturnType<typeof setTimeout> | undefined;
let persistPromise = Promise.resolve();
interface PersistedProfiles {
export interface PersistedProfiles {
version: typeof STORE_VERSION;
profiles: Record<string, TransferPerformanceProfile>;
directRoutes: Record<string, DirectRouteProfile>;
@@ -68,12 +82,6 @@ function validDirectRoute(value: unknown): value is DirectRouteProfile {
);
}
function storePath(): string {
const dataDir =
process.env.DATA_DIR || path.join(process.cwd(), "db", "data");
return path.join(dataDir, STORE_FILENAME);
}
function profileId(key: string): string {
return createHash("sha256").update(key).digest("hex");
}
@@ -117,22 +125,15 @@ function trimProfiles(now = Date.now()): void {
async function persistProfiles(): Promise<void> {
trimProfiles();
const target = storePath();
const temporary = `${target}.${process.pid}.tmp`;
const payload: PersistedProfiles = {
version: STORE_VERSION,
profiles: Object.fromEntries(profiles),
directRoutes: Object.fromEntries(directRoutes),
};
if (!store) return;
try {
await fs.mkdir(path.dirname(target), { recursive: true });
await fs.writeFile(temporary, JSON.stringify(payload), {
encoding: "utf8",
mode: 0o600,
await store.write({
version: STORE_VERSION,
profiles: Object.fromEntries(profiles),
directRoutes: Object.fromEntries(directRoutes),
});
await fs.rename(temporary, target);
} catch {
await fs.rm(temporary, { force: true }).catch(() => {});
// Learning data is a nicety; a failed write must not affect transfers.
}
}
@@ -146,16 +147,16 @@ function queuePersist(): void {
}
export async function initializeTransferProfiles(): Promise<void> {
const target = storePath();
if (loadedPath === target) return loadPromise;
loadedPath = target;
if (loadPromise && loadedStore === store) return loadPromise;
loadedStore = store;
const current = store;
loadPromise = (async () => {
profiles.clear();
directRoutes.clear();
if (!current) return;
try {
const parsed = JSON.parse(
await fs.readFile(target, "utf8"),
) as Partial<PersistedProfiles>;
const parsed = ((await current.read()) ??
{}) as Partial<PersistedProfiles>;
if (parsed.version !== STORE_VERSION || !parsed.profiles) return;
for (const [key, profile] of Object.entries(parsed.profiles)) {
if (/^[a-f0-9]{64}$/.test(key) && validProfile(profile)) {
@@ -381,7 +382,7 @@ export function getRecentDirectRouteDecision(
export function clearTransferProfiles(): void {
if (persistTimer) clearTimeout(persistTimer);
persistTimer = undefined;
loadedPath = undefined;
loadedStore = null;
loadPromise = undefined;
profiles.clear();
directRoutes.clear();