fix: preserve tran script command separator

This commit is contained in:
Codex
2026-05-25 15:32:56 +00:00
parent 073213c302
commit 964cc7e984
5 changed files with 41 additions and 7 deletions
+1
View File
@@ -170,6 +170,7 @@ export function sshHelp(): unknown {
notes: [
"ssh --help and ssh <route> --help print this JSON help and never open an interactive session.",
"For non-interactive remote commands, prefer argv for a single process and script/stdin for shell logic.",
"When a short remote command is easier to type through the script path and needs dash-prefixed argv, write `script -- <command> [args...]`; this direct form does not wait for stdin, and the command-local `--` is preserved by local and remote `tran` parsing, so examples such as `tran D601:/work script -- sed -n '1,20p' file` do not require a heredoc just to pass `-n`.",
"For arbitrary stdin streams into a workload command, use a workload route plus `exec --stdin -- <command> ...`; this keeps the route as location-only and avoids heredoc/base64/tar shell wrapping.",
"apply-patch rejects low-context update hunks by default, reports the matched file:line for each hunk on stderr, and only accepts --allow-loose when the caller has manually reviewed an intentionally ambiguous insertion.",
"script defaults to target /bin/sh and inherits provider proxy variables such as HTTP_PROXY/HTTPS_PROXY/ALL_PROXY/NO_PROXY; use --shell bash only for bash syntax such as pipefail, arrays, or [[ ... ]], not as a proxy workaround.",
+6 -2
View File
@@ -161,8 +161,12 @@ export function extractRemoteCliOptions(argv: string[]): RemoteCliOptions {
for (let index = 0; index < argv.length; index += 1) {
const arg = argv[index] ?? "";
if (arg === "--") {
rest.push(...argv.slice(index + 1));
break;
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);
+15 -3
View File
@@ -806,7 +806,7 @@ export function parseSshArgs(args: string[]): ParsedSshArgs {
return { remoteCommand: buildPythonStdinCommand(args.slice(1)), requiresStdin: true, invocationKind: "helper" };
}
if (subcommand === "script" || subcommand === "sh") {
return { remoteCommand: buildShellStdinCommand(args.slice(1)), requiresStdin: true, invocationKind: "helper" };
return buildShellCommand(args.slice(1));
}
if (subcommand === "argv" || subcommand === "exec") {
const toolArgs = args.slice(1);
@@ -1446,10 +1446,12 @@ function k3sScriptShell(value: string, option: string): string {
return value;
}
function buildShellStdinCommand(args: string[]): string {
function buildShellCommand(args: string[]): ParsedSshArgs {
let shell = "sh";
const scriptArgs: string[] = [];
let afterDoubleDash = false;
let directArgvMode = false;
let shellOptionSeen = false;
for (let index = 0; index < args.length; index += 1) {
const arg = args[index] ?? "";
if (afterDoubleDash) {
@@ -1457,18 +1459,28 @@ function buildShellStdinCommand(args: string[]): string {
continue;
}
if (arg === "--") {
if (!shellOptionSeen && scriptArgs.length === 0) {
directArgvMode = true;
scriptArgs.push(...args.slice(index + 1));
break;
}
afterDoubleDash = true;
continue;
}
if (arg === "--shell") {
shell = k3sScriptShell(k3sOptionValue(args, index, "ssh script --shell"), "ssh script --shell");
shellOptionSeen = true;
index += 1;
continue;
}
if (arg.startsWith("-")) throw new Error(`unsupported ssh script option: ${arg}`);
scriptArgs.push(arg);
}
return shellArgv([shell, "-s", "--", ...scriptArgs]);
if (directArgvMode) {
if (scriptArgs.length === 0) throw new Error("ssh script -- requires a command");
return { remoteCommand: shellArgv(scriptArgs), requiresStdin: false, invocationKind: "argv" };
}
return { remoteCommand: shellArgv([shell, "-s", "--", ...scriptArgs]), requiresStdin: true, invocationKind: "helper" };
}
function podApplyPatchStdinWrapper(): { prefix: string; suffix: string } {