fix: isolate trans ssh bootstrap

This commit is contained in:
Codex
2026-06-19 15:43:54 +00:00
parent 1c371c7431
commit f9e11ff93e
8 changed files with 1152 additions and 13 deletions
+91
View File
@@ -0,0 +1,91 @@
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;
}
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -3180,8 +3180,8 @@ async function runSshStreamRemoteCommand(
}
async function runRemoteSsh(config: UniDeskConfig, host: string, providerId: string, args: string[]): Promise<number> {
const { runRemoteCli } = await import("./remote");
return await runRemoteCli({
const { runRemoteSshCli } = await import("./remote-ssh");
return await runRemoteSshCli({
host,
user: "root",
port: 22,
@@ -3212,7 +3212,7 @@ export async function runSshCommandCapture(config: UniDeskConfig, target: string
}
async function runRemoteSshCapture(config: UniDeskConfig, host: string, target: string, args: string[], input?: string): Promise<SshCaptureResult> {
const { runRemoteSshCommandCapture } = await import("./remote");
const { runRemoteSshCommandCapture } = await import("./remote-ssh");
return await runRemoteSshCommandCapture(config, host, target, args, input);
}
+47
View File
@@ -0,0 +1,47 @@
import { readConfig } from "./src/config";
import { isHelpToken, sshHelp } from "./src/help";
import { emitError, emitJson } from "./src/output";
import { extractRemoteCliOptions } from "./src/remote-options";
import { runRemoteSshCli } from "./src/remote-ssh";
import { runSsh } from "./src/ssh";
const remoteOptions = extractRemoteCliOptions(process.argv.slice(2));
const args = normalizeSshCommandArgs(remoteOptions.args);
const commandName = args.join(" ") || "ssh";
function normalizeSshCommandArgs(rawArgs: string[]): string[] {
if (rawArgs[0] === "ssh") return rawArgs;
return ["ssh", ...rawArgs];
}
function isGhContentRouteTarget(target: string | undefined): boolean {
return typeof target === "string" && target.startsWith("gh:");
}
async function main(): Promise<void> {
const [top, sub, third] = args;
if (top !== "ssh") throw new Error(`ssh-cli supports only the ssh command, got: ${top || "<empty>"}`);
if (sub === undefined || isHelpToken(sub) || (isHelpToken(third) && args.length === 3)) {
emitJson(commandName, sshHelp());
return;
}
if (remoteOptions.host !== null) {
process.exitCode = await runRemoteSshCli({ ...remoteOptions, args }, readConfig());
return;
}
if (isGhContentRouteTarget(sub)) {
const { runGhContentRoute } = await import("./src/gh-route");
process.exitCode = await runGhContentRoute(sub, args.slice(2));
return;
}
process.exitCode = await runSsh(readConfig(), sub, args.slice(2));
}
main().catch((error) => {
emitError(commandName, error);
process.exitCode = 1;
});
+3 -3
View File
@@ -2,7 +2,7 @@
set -eu
repo=${UNIDESK_TRAN_REPO_ROOT:-/root/unidesk}
if [ ! -f "$repo/scripts/cli.ts" ]; then
if [ ! -f "$repo/scripts/ssh-cli.ts" ]; then
self_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
repo=$(CDPATH= cd -- "$self_dir/.." && pwd)
fi
@@ -49,8 +49,8 @@ if [ -n "${CODE_QUEUE_SERVICE_ROLE:-}" ] || [ -n "${CODE_QUEUE_INSTANCE_ID:-}" ]
fi
if [ "$runner_env" = 1 ] && [ -n "$host" ] && [ "${UNIDESK_TRAN_LOCAL:-}" != "1" ]; then
bun "$repo/scripts/cli.ts" --main-server-ip "$host" ssh "$@"
bun "$repo/scripts/ssh-cli.ts" --main-server-ip "$host" ssh "$@"
exit $?
fi
bun "$repo/scripts/cli.ts" ssh "$@"
bun "$repo/scripts/ssh-cli.ts" ssh "$@"
+2 -2
View File
@@ -2,9 +2,9 @@
set -eu
repo=${UNIDESK_TRANS_REPO_ROOT:-/root/unidesk}
if [ ! -f "$repo/scripts/cli.ts" ]; then
if [ ! -f "$repo/scripts/ssh-cli.ts" ]; then
self_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
repo=$(CDPATH= cd -- "$self_dir/.." && pwd)
fi
exec bun "$repo/scripts/cli.ts" ssh "$@"
exec bun "$repo/scripts/ssh-cli.ts" ssh "$@"