> ## Documentation Index
> Fetch the complete documentation index at: https://klyx.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Process Execution

> Run shell commands, spawn processes, and stream output

Klyx provides a `command()` DSL for running programs and shell commands. It supports synchronous execution, asynchronous spawning, and streaming output via Kotlin coroutines.

## Running commands

### Basic execution

```kotlin theme={null}
val output = command("echo", "Hello, world!").output()
println(output.stdoutText)  // "Hello, world!"
println(output.exitCode)    // 0
```

### Shell commands

```kotlin theme={null}
val result = shell("ls -la /data/data/com.klyx").outputText()
```

### Adding arguments

```kotlin theme={null}
val output = command("ls")
    .arg("-la")
    .args("/path/to/dir", "/another/path")
    .outputText()
```

### Environment variables

```kotlin theme={null}
val output = command("myapp")
    .env("HOME", "/data/data/com.klyx/files")
    .env(mapOf("PATH" to "/usr/bin:/bin"))
    .output()
```

### Working directory

```kotlin theme={null}
val output = command("git", "status")
    .cwd(Paths.projects)
    .outputText()
```

## Synchronous output

```kotlin theme={null}
// Get stdout as text
val text: String = command("echo", "hi").outputText()

// Get stdout as lines
val lines: List<String> = command("ls").outputLines()

// Check success/failure
val success: Boolean = command("test", "-f", path).isSuccess()
val failed: Boolean = command("false").isFailure()

// Get full output with exit code
val result: ProcessOutput = command("ls").output()
result.exitCode     // Int
result.stdoutText   // String
result.stderrText   // String
result.stdout       // ByteArray
result.stderr       // ByteArray
```

## Streaming output

```kotlin theme={null}
// Stream stdout line by line
command("logcat").stream().collect { event ->
    when (event) {
        is ProcessOutputEvent.Stdout -> println(event.data.decodeToString())
        is ProcessOutputEvent.Stderr -> System.err.println(event.data.decodeToString())
        is ProcessOutputEvent.ExitCode -> println("Exited with ${event.code}")
    }
}

// Alternative stream helpers
command("ping", "-c", "4", "google.com").streamLines().collect { line ->
    println(line)
}
command("some-command").streamErrLines().collect { line ->
    System.err.println(line)
}
command("log").combinedLines().collect { line ->
    println(line)
}
command("build").stdoutBytes().collect { chunk ->
    // Process binary output
}
command("build").stderrBytes().collect { chunk ->
    // Process binary error output
}
```

## Spawning processes

```kotlin theme={null}
val process: ChildProcess = command("myserver").spawn()

// Wait for completion
val output: ProcessOutput = process.waitFor()
val outputOrNull: ProcessOutput? = process.waitForTimeout(5000)

// Stream output from a running process
process.streamLines().collect { line -> println(line) }

// Control the process
process.pid       // Process ID
process.isRunning // Check if running
process.kill()    // SIGKILL
process.terminate() // SIGTERM
```

## Utility functions

```kotlin theme={null}
// Check if a program exists
val exists: Boolean = commandExists("git")

// Find the full path of a program
val path: String? = which("python3")

// Find the first available program
val available: String? = firstAvailable("node", "nodejs", "deno")

// Run a command wrapped in shell
shell("curl https://api.example.com").output()

// Pipe commands
command("echo", "hello").pipeTo(command("wc", "-c"))
```

## Advanced execution

```kotlin theme={null}
// Timeout
val result: ProcessOutput? = command("slow-command").outputWithTimeout(10.seconds)

// Retry on failure
val result: ProcessOutput = command("flaky-command").retry(times = 3)

// Result wrapper
val result: Result<ProcessOutput> = command("risky-command").result()
result.getOrNull()  // ProcessOutput? on success
result.exceptionOrNull()  // Throwable? on failure

// Input to stdin
command("sort")
    .stdin("c\na\nb")
    .outputLines()  // [a, b, c]

command("sort")
    .stdin(byteArrayOf(...))
    .output()
```

## Stdin sources

```kotlin theme={null}
StdinSource.Inherit   // Inherit from parent
StdinSource.Pipe      // Pipe (no initial input)
StdinSource.Bytes(data) // Provide bytes
```

## Stdio destinations

```kotlin theme={null}
StdioDest.Inherit     // Inherit from parent
StdioDest.Capture     // Capture in ProcessOutput
StdioDest.Null        // Discard
StdioDest.File(file)  // Write to file
```
