Skip to content
GitHub Get Started
Operating System

Processes & Shell

Run commands with one-shot exec, spawn long-running processes with streaming stdout/stderr and stdin, manage their lifecycle (stop, kill, wait, inspect), open interactive PTY-backed shells, and inspect the process tree across all VM runtimes.

Use exec to run a command and wait for completion. Returns stdout, stderr, and exit code.

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const result = await client.vm.getOrCreate("my-agent").exec("echo hello && ls /home/agentos");
console.log("stdout:", result.stdout);
console.log("stderr:", result.stderr);
console.log("exit code:", result.exitCode);

See Full Example

Use spawn for processes that run in the background. Output is streamed via processOutput and processExit events.

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const conn = agent.connect();
// Subscribe to process output
conn.on("processOutput", (data) => {
const text = new TextDecoder().decode(data.data);
console.log(`[pid ${data.pid}] ${data.stream}: ${text}`);
});
conn.on("processExit", (data) => {
console.log(`[pid ${data.pid}] exited with code ${data.exitCode}`);
});
// Spawn a dev server
const { pid } = await agent.spawn("node", ["/home/agentos/server.js"]);
console.log("Started process:", pid);

See Full Example

Send input to a running process.

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const { pid } = await agent.spawn("cat", []);
// Write to stdin
await agent.writeProcessStdin(pid, "hello from stdin\n");
// Close stdin when done
await agent.closeProcessStdin(pid);
// Wait for the process to exit
const exitCode = await agent.waitProcess(pid);
console.log("exit code:", exitCode);

See Full Example

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const { pid } = await agent.spawn("node", ["/home/agentos/server.js"]);
// List all processes tracked by the VM
const processes = await agent.listProcesses();
for (const p of processes) {
console.log(p.pid, p.command, p.args.join(" "), p.running ? "running" : "exited");
}
// Inspect a specific process by pid
const info = await agent.getProcess(pid);
console.log(info.running, info.exitCode);
// Graceful stop (SIGTERM)
await agent.stopProcess(pid);
// Force kill (SIGKILL)
await agent.killProcess(pid);

See Full Example

Open an interactive shell with PTY support. Shell data is streamed via shellData events.

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const conn = agent.connect();
// Subscribe to shell output
conn.on("shellData", (data) => {
const text = new TextDecoder().decode(data.data);
process.stdout.write(text);
});
// Open a shell
const { shellId } = await agent.openShell();
// Write commands to the shell
await agent.writeShell(shellId, "ls -la /home/agentos\n");
// Resize the terminal
await agent.resizeShell(shellId, 120, 40);
// Close the shell when done
await agent.closeShell(shellId);

See Full Example