pub fn spawn_streaming<F>(
program: PathBuf,
args: Vec<String>,
env: Vec<(String, String)>,
cwd: PathBuf,
run_id: String,
callback: F,
) -> Result<ProcessHandle, StreamError>Expand description
Spawn an arbitrary streaming child process — the generic engine behind every process-backed harness (bob, Claude Code, Codex).
Pipes stdout/stderr line-by-line through callback using the raw
ProcessEvent vocabulary (Started / Stdout / Stderr / Error /
Exited). env supplies per-harness secrets (each harness’s API-key
var, or none for self-authenticating CLIs). PATH is augmented so
Node-based CLIs find node. Returns a ProcessHandle for
cancellation.
callback is invoked from three threads (stdout reader, stderr
reader, exit watcher); the Clone bound lets us hand a copy to each.
run_id is opaque — the caller chooses it and uses it to correlate
events with the handle.
use cli_stream::{spawn_streaming, ProcessEvent};
use std::path::PathBuf;
let handle = spawn_streaming(
PathBuf::from("echo"),
vec!["hello".to_owned()],
Vec::new(), // extra env vars (key, value)
std::env::current_dir().unwrap(),
"run-1".to_owned(), // your correlation id
|event| match event {
ProcessEvent::Stdout { line, .. } => println!("{line}"),
ProcessEvent::Exited { exit_code, .. } => eprintln!("exit {exit_code:?}"),
_ => {}
},
)?;
// `handle.cancel()` stops it early; dropping the handle does not.
let _ = handle;