# Package: dirigent_taskrunner

Background task runner for managing child processes with output capture.

## Quick Facts
- **Type**: Library
- **Main Entry**: src/lib.rs
- **Dependencies**: tokio, serde, chrono, thiserror, tracing, uuid

## Overview

The dirigent_taskrunner package provides a `TaskRunner` service that spawns, manages, and captures output from arbitrary shell commands. Tasks are defined with a title, slug name, command, arguments, and various options (working directory, startup behavior, output persistence, log rotation).

## Architecture

### Core Types

- **TaskDefinition** — Configuration for a task: command, args, cwd, run_at_startup, persist_to_disk, rotate_previous, env vars
- **TaskStatus** — Runtime state enum: Stopped, Running{pid}, Finished{exit_code}, Failed{error}
- **TaskInfo** — Definition + status + timestamps (started_at, stopped_at)
- **OutputKind** — Stdout, Stderr, Combined
- **TaskId** — String alias (the task slug/name)

### TaskRunner

The main service. Uses interior mutability (RwLock) — all methods take `&self`. Designed to be wrapped in `Arc` and shared across async tasks.

Key operations:
- `register(def)` — Add a task definition
- `start(name)` — Spawn the process, capture stdout/stderr to files
- `stop(name)` — Kill the process
- `poll_completed()` — Check running processes for exit (called from periodic timer)
- `list_tasks()` — Get all tasks with status
- `read_output(name, kind, tail_lines)` — Read captured output
- `remove(name)` — Delete a task definition

### Output Storage

Output is stored in `{tasks_dir}/{task_name}/`:
- `stdout.log` — Captured stdout
- `stderr.log` — Captured stderr
- `combined.log` — Interleaved with `[stdout]`/`[stderr]` prefixes

Log rotation creates `.log.1`, `.log.2`, etc.

## Integration

- **Config**: `CoreConfig.tasks: Vec<TaskConfig>` in dirigent.toml (`[[tasks]]` sections)
- **Runtime**: `CoreRuntime.task_runner_slot()` holds `Arc<RwLock<Option<Arc<TaskRunner>>>>`
- **API**: Server functions in `api::tasks` (list, start, stop, output, create, update, delete)
- **UI**: Tasks ribbon mode + Configuration > Tasks section
- **Inspector**: Registered as `dirigent/services/task-runner`
- **Paths**: `DirigentPaths::tasks_dir()` returns `{data_dir}/tasks/`

## Configuration Example

```toml
[[tasks]]
name = "lspmux"
title = "LSP Mux Server"
command = "lspmux"
args = ["server"]
run_at_startup = true
persist_to_disk = true
rotate_previous = true
```

## Key Files

- `src/types.rs` — TaskDefinition, TaskStatus, TaskInfo, OutputKind
- `src/runner.rs` — TaskRunner service, TaskError
- `src/output.rs` — TaskOutputManager (file I/O, rotation)
- `src/lib.rs` — Public exports
