125 lines · 3.4 KB · TypeScript
RawDownload
import { spawnSync } from "node:child_process";import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";import { tmpdir } from "node:os";import { dirname, join } from "node:path";import { fileURLToPath } from "node:url";import { describe, expect, test } from "vitest"; const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));const cliPath = join(packageRoot, "dist", "main.js"); function runCli(args: string[], input?: string) {	return spawnSync(process.execPath, [cliPath, ...args], {		cwd: packageRoot,		encoding: "utf8",		input,		timeout: 60_000,	});} describe("agentos-shell cli", () => {	test("--help prints Docker-style run flags without starting a VM", () => {		const result = runCli(["--help"]); 		expect(result.status).toBe(0);		expect(result.stdout).toContain("agentos-shell");		expect(result.stdout).toContain("-i, --interactive");		expect(result.stdout).toContain("--no-interactive");		expect(result.stdout).toContain("-t, --tty");		expect(result.stdout).toContain("--no-tty");		expect(result.stdout).toContain("-e, --env <env>");		expect(result.stdout).toContain("-v, --volume <spec>");		expect(result.stderr).not.toContain("agent-os shell");	}); 	test("runs a VM-backed command with guest cwd and env", () => {		const result = runCli([			"--workdir",			"/tmp",			"--env",			"SHELL_TEST_ENV=works",			"--",			"node",			"-e",			"console.log('SHELL_VM_COMMAND:' + process.cwd() + ':' + process.env.SHELL_TEST_ENV); process.exit(7);",		]); 		expect(result.status).toBe(7);		expect(result.stdout).toContain("SHELL_VM_COMMAND:/tmp:works");	}); 	test("mounts a host directory with Docker -v syntax", () => {		const hostDir = mkdtempSync(join(tmpdir(), "agentos-shell-volume-"));		writeFileSync(join(hostDir, "hello.txt"), "mounted\n"); 		const result = runCli([			"--volume",			`${hostDir}:/mnt:ro`,			"--",			"cat",			"/mnt/hello.txt",		]); 		expect(result.status).toBe(0);		expect(result.stdout).toContain("mounted");	}); 	test("keeps stdin attached by default", () => {		const result = runCli(["--", "bash"], "echo hello\n"); 		expect(result.status).toBe(0);		expect(result.stdout).toContain("hello");	}); 	test("detaches stdin when --no-interactive is set", () => {		const result = runCli(			["--no-interactive", "--", "bash"],			"echo should-not-run\n",		); 		expect(result.status).toBe(0);		expect(result.stdout).not.toContain("should-not-run");	}); 	test("runs a command through terminal mode when -t is set", () => {		const result = runCli([			"--workdir",			"/tmp",			"--tty",			"--",			"bash",			"-c",			"echo tty-mode",		]); 		expect(result.status).toBe(0);		expect(result.stdout).toContain("tty-mode");	}); 	test("default terminal mode launches bash instead of the synthetic shell", () => {		const result = runCli([], "echo $0\nexit\n"); 		expect(result.status).toBe(0);		expect(result.stdout).toContain("bash");		expect(result.stdout).not.toContain("sh-0.4$");	}); 	test("reads env files", () => {		const dir = mkdtempSync(join(tmpdir(), "agentos-shell-env-"));		mkdirSync(join(dir, "nested"));		const envFile = join(dir, "nested", "env.list");		writeFileSync(envFile, "FROM_ENV_FILE=yes\n"); 		const result = runCli([			"--env-file",			envFile,			"--",			"node",			"-e",			"console.log(process.env.FROM_ENV_FILE)",		]); 		expect(result.status).toBe(0);		expect(result.stdout).toContain("yes");	});});