import assert from "node:assert/strict"; import test from "node:test"; import { createRemoteBashOps } from "../src/remote-bash.ts"; import type { RemoteExecOptions, RemoteTransport } from "../src/ssh2-transport.ts"; class CapturingTransport implements RemoteTransport { calls: Array<{ command: string; cwd: string }> = []; connect(): Promise { return Promise.resolve(); } dispose(): Promise { return Promise.resolve(); } exec(command: string, cwd: string, options: RemoteExecOptions): Promise<{ exitCode: number | null }> { this.calls.push({ command, cwd }); options.onData(Buffer.from("ok\n")); return Promise.resolve({ exitCode: 0 }); } capture(): Promise<{ exitCode: number | null; output: Buffer }> { throw new Error("not used"); } readFile(): Promise { throw new Error("not used"); } ensureReadable(): Promise { throw new Error("not used"); } ensureReadableWritable(): Promise { throw new Error("not used"); } detectImageMimeType(): Promise { throw new Error("not used"); } mkdir(): Promise { throw new Error("not used"); } writeFile(): Promise { throw new Error("not used"); } } test("ssh_bash always executes from the active remote cwd", async () => { const connection = { remoteCwd: "/srv/project" }; const transport = new CapturingTransport(); const operations = createRemoteBashOps(connection, transport); await operations.exec("pwd", "/Users/local/project", { onData() {} }); assert.deepEqual(transport.calls, [{ command: "pwd", cwd: "/srv/project" }]); connection.remoteCwd = "/opt/next-project"; await operations.exec("npm test", "/another/local/path", { onData() {} }); assert.deepEqual(transport.calls[1], { command: "npm test", cwd: "/opt/next-project" }); }); test("ssh_bash rejects an invalid non-absolute remote cwd", () => { const operations = createRemoteBashOps({ remoteCwd: "relative/path" }, new CapturingTransport()); assert.throws( () => operations.exec("pwd", "/Users/local/project", { onData() {} }), /requires an absolute remote cwd/, ); });