55 lines
3.3 KiB
TypeScript
55 lines
3.3 KiB
TypeScript
import { sshHelp } from "./src/help";
|
|
import { providerTriageRecommendedCrossChecks } from "./src/provider-triage";
|
|
import { formatSshFailureHint, parseSshArgs, sshFailureHint } from "./src/ssh";
|
|
|
|
type JsonRecord = Record<string, unknown>;
|
|
|
|
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
|
|
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
|
|
}
|
|
|
|
export function runSshArgvGuidanceContract(): JsonRecord {
|
|
const argv = parseSshArgs(["argv", "bash", "-lc", "echo ok"]);
|
|
assertCondition(argv.invocationKind === "argv", "argv subcommand must be classified as argv", argv);
|
|
assertCondition(argv.remoteCommand === "'bash' '-lc' 'echo ok'", "argv command must shell-quote each token", argv);
|
|
assertCondition(argv.requiresStdin === false, "argv command must not require stdin", argv);
|
|
assertCondition(sshFailureHint("D601", argv, 255, "kex_exchange_identification: Connection closed by remote host") === null, "argv failures must not produce ssh-like friction hint", argv);
|
|
|
|
const shortcut = parseSshArgs(["pwd"]);
|
|
assertCondition(shortcut.invocationKind === "argv", "safe command shortcuts must use argv quoting", shortcut);
|
|
assertCondition(shortcut.remoteCommand === "'pwd'", "safe command shortcut should be shell-quoted", shortcut);
|
|
|
|
const sshLike = parseSshArgs(["echo hello"]);
|
|
const hint = sshFailureHint("D601", sshLike, 255, "kex_exchange_identification: Connection closed by remote host");
|
|
assertCondition(hint !== null, "ssh-like kex failure must produce a hint", sshLike);
|
|
assertCondition(hint?.try === "bun scripts/cli.ts ssh D601 argv bash -lc '<command>'", "hint must provide canonical argv retry", hint);
|
|
assertCondition(hint?.triage.includes("provider triage D601"), "hint must provide provider triage command", hint);
|
|
const formatted = formatSshFailureHint(hint!);
|
|
assertCondition(formatted.startsWith("UNIDESK_SSH_HINT "), "formatted hint must have structured prefix", formatted);
|
|
assertCondition(!formatted.includes("echo hello"), "formatted hint must not echo the original remote command", formatted);
|
|
|
|
const timeoutHint = sshFailureHint("D601", sshLike, 255, "unidesk ssh bridge timed out waiting for provider session");
|
|
assertCondition(timeoutHint?.trigger === "timeout-or-kex", "provider session timeout must map to timeout-or-kex", timeoutHint);
|
|
|
|
const helpText = JSON.stringify(sshHelp());
|
|
assertCondition(helpText.includes("ssh D601 argv bash -lc '<command>'"), "ssh help must recommend argv bash -lc for non-interactive commands", helpText);
|
|
assertCondition(helpText.includes("UNIDESK_SSH_HINT"), "ssh help must document structured failure hint", helpText);
|
|
|
|
const crossChecks = providerTriageRecommendedCrossChecks("D601");
|
|
assertCondition(crossChecks.includes("bun scripts/cli.ts ssh D601 argv true"), "provider triage cross-checks must keep argv true", crossChecks);
|
|
|
|
return {
|
|
ok: true,
|
|
checks: [
|
|
"argv form is classified and quoted as the success path for non-interactive commands",
|
|
"ssh-like timeout/kex failures emit one structured argv retry hint",
|
|
"help text documents argv bash -lc and UNIDESK_SSH_HINT",
|
|
"provider triage recommendedCrossChecks keeps ssh D601 argv true",
|
|
],
|
|
};
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
process.stdout.write(`${JSON.stringify(runSshArgvGuidanceContract(), null, 2)}\n`);
|
|
}
|