export interface RemoteCliOptions { host: string | null; user: string; port: number; projectRoot: string; identityFile: string | null; transport: "auto" | "frontend" | "ssh"; args: string[]; } const hostOptions = new Set(["--main-server-ip", "--main-server", "--server"]); const userOptions = new Set(["--main-server-user", "--server-user"]); const portOptions = new Set(["--main-server-port", "--server-port"]); const rootOptions = new Set(["--main-server-root", "--server-root"]); const keyOptions = new Set(["--main-server-key", "--server-key"]); const transportOptions = new Set(["--main-server-transport", "--server-transport"]); function positivePort(raw: string, option: string): number { const value = Number(raw); if (!Number.isInteger(value) || value <= 0 || value > 65535) throw new Error(`${option} must be a TCP port from 1 to 65535`); return value; } function requiredValue(argv: string[], index: number, option: string): string { const value = argv[index + 1]; if (value === undefined || value.length === 0) throw new Error(`${option} requires a non-empty value`); return value; } function transportValue(raw: string, option: string): RemoteCliOptions["transport"] { if (raw === "auto" || raw === "frontend" || raw === "ssh") return raw; throw new Error(`${option} must be one of: auto, frontend, ssh`); } export function extractRemoteCliOptions(argv: string[]): RemoteCliOptions { const rest: string[] = []; const options: RemoteCliOptions = { host: null, user: "root", port: 22, projectRoot: "/root/unidesk", identityFile: null, transport: "auto", args: rest, }; for (let index = 0; index < argv.length; index += 1) { const arg = argv[index] ?? ""; if (arg === "--") { if (rest.length === 0) { rest.push(...argv.slice(index + 1)); break; } rest.push(arg); continue; } if (hostOptions.has(arg)) { options.host = requiredValue(argv, index, arg); index += 1; continue; } if (userOptions.has(arg)) { options.user = requiredValue(argv, index, arg); index += 1; continue; } if (portOptions.has(arg)) { options.port = positivePort(requiredValue(argv, index, arg), arg); index += 1; continue; } if (rootOptions.has(arg)) { options.projectRoot = requiredValue(argv, index, arg); index += 1; continue; } if (keyOptions.has(arg)) { options.identityFile = requiredValue(argv, index, arg); index += 1; continue; } if (transportOptions.has(arg)) { options.transport = transportValue(requiredValue(argv, index, arg), arg); index += 1; continue; } rest.push(arg); } return options; }