/** * Thin shell wrappers around `ssh` + `scp` so deploy/teardown can talk * to the consumer's box without pulling in a JS ssh library. * * Why shell out: ops people debug `ssh` + `scp` invocations daily; if a * deploy fails, the failing command is something they can copy + paste. * Pulling in a JS library for marginal API ergonomics adds a maintenance * surface for a feature that's already box-specific. * * All wrappers use BatchMode=yes (no interactive password prompts) and * StrictHostKeyChecking=accept-new (first connect adds the key, future * connects verify against it). Failures throw with stderr captured so * the workflow logs surface the underlying error. */ export interface SshTarget { host: string; user: string; port: number; /** Absolute path to the private key file on the runner's filesystem. */ keyPath: string; } export interface SshResult { stdout: string; stderr: string; } /** * Run a remote command via ssh. Throws on non-zero exit with the * captured stderr inlined into the error message. */ export declare function sshExec(target: SshTarget, command: string): SshResult; /** * scp a local file to a remote path. Throws on non-zero exit. */ export declare function scpUpload(target: SshTarget, localPath: string, remotePath: string): void; /** * Find the first free TCP port in [lo, hi] on the remote box. Uses * `ss -ltn` (universally available on modern Linux) to enumerate * already-bound ports. * * Returns the chosen port. Throws if every port in the range is in use. */ export declare function pickRemotePort(target: SshTarget, lo: number, hi: number): number; /** * Get the host port a running container is publishing to (the value * after `0.0.0.0:` in `docker port` output). Returns null if the * container isn't running or doesn't publish 3100. */ export declare function getContainerPort(target: SshTarget, containerName: string): number | null; //# sourceMappingURL=ssh.d.ts.map