# `Mutare.Report.Live.Lines`
[🔗](https://github.com/foxbenjaminfox/mutare/blob/v0.2.1/lib/mutare/report/live/lines.ex#L1)

The text of the live display, rendered from the reporter's state.

`Mutare.Report.Live` manages the process, output modes, and terminal writes; every line it
draws or leaves in scrollback is rendered here — the animated status block
(`status_block/2`), a mutant's leave-behind or `--verbose` line, a phase's label or
detail note, and compile-poison diagnostics. Nothing here touches the terminal, so
each line is testable on its own. Cursor-control sequences are the reporter's, never
part of a line.

# `confirming_label`

```elixir
@spec confirming_label(non_neg_integer()) :: String.t()
```

The label announcing the post-stream timeout-confirmation pass.

# `detail_line`

```elixir
@spec detail_line(tuple()) :: String.t()
```

Renders a verbose detail event as a persistent status line: a phase's completion, or a
`mix.exs` whose inference override did not land.

# `eta_secs`

```elixir
@spec eta_secs(non_neg_integer(), non_neg_integer(), non_neg_integer()) ::
  non_neg_integer() | nil
```

Estimates remaining seconds from completed work, remaining work, and elapsed
seconds.

Returns `nil` until at least one item has completed and elapsed time is non-zero.

# `humanize_ms`

```elixir
@spec humanize_ms(non_neg_integer()) :: String.t()
```

Milliseconds as one-decimal seconds (e.g. `450 → "0.5s"`, `3100 → "3.1s"`).

# `humanize_secs`

```elixir
@spec humanize_secs(non_neg_integer()) :: String.t()
```

Seconds as `Ns` (under a minute) or `Nm Ss`.

# `leave_behind`

```elixir
@spec leave_behind(Mutare.Result.status()) :: {String.t(), atom()} | nil
```

Returns the persistent `{label, color}` for `status`, or `nil` when the status
only updates the counter.

# `leave_line`

```elixir
@spec leave_line({String.t(), atom()}, Mutare.Result.t(), boolean()) :: String.t()
```

A mutant's permanent line: its `leave_behind/1` styling (coloured when `color?`), the
mutant descriptor, and — for a harness error — the compact diagnostic.

# `macro_poison_line`

```elixir
@spec macro_poison_line(map()) :: String.t()
```

Renders the macro-expansion poison fallback as a loud, persistent warning: names the
inline DSL macro(s) whose argument wouldn't compile with a mutation spliced in, and the
copy-paste route to pin the skip up front (`Mutare.Poison.Hint.route_tuple/2` — `:raw`
for a call, `:skip` for a head Mutare analyzes structurally), or a `# mutare:ignore`
pointer when no route can name any of them.

# `phase_label`

```elixir
@spec phase_label(term()) :: String.t() | nil
```

The label of a pre-mutant phase (`:scanning`, `:compiling`, `:baseline`,
`:coverage_probe`), or `nil` for anything else.

# `poison_round_line`

```elixir
@spec poison_round_line(map()) :: String.t()
```

Renders one compile-poison recovery round as a persistent status line: how many
mutants were dropped and how many block macros were escalated (skipped wholesale),
naming the escalated macros so the line explains *why* the compile is being retried.

# `running_label`

```elixir
@spec running_label(map(), non_neg_integer()) :: String.t()
```

The `:running` phase's label. In verbose mode it appends the worker count from the
stashed `:run_config` (`{:run_config, cfg}` always fires just before
`{:running, total}`); the non-verbose label is unchanged.

# `seed_line`

```elixir
@spec seed_line(map()) :: String.t() | nil
```

Renders the app-build seed's outcome (`Mutare.Sandbox.Seed.summary/0`) as a persistent
status line, or `nil` for a `:skipped` seed (the broad-run default — no line even in
verbose). `:seeded` shows the reused vs recompiling beam counts; `:partial` adds how many
apps fell back (an umbrella per-app miss); `:fallback` names the otherwise-silent fall
back to a cold compile.

# `status_block`

```elixir
@spec status_block(map(), integer()) :: [String.t()]
```

Returns the status-block lines for `state` at monotonic time `now_ms`.

A running phase has an activity line and a counter. A pre-run phase has one
line. An idle state has none. Cursor-control sequences are not included.

# `verbose_leave`

```elixir
@spec verbose_leave(Mutare.Result.status()) :: {String.t(), atom()}
```

Returns the persistent `{label, color}` for `status` in verbose mode.

Every registered status has a verbose label. An unknown status raises.

# `verbose_line`

```elixir
@spec verbose_line(Mutare.Result.t(), boolean()) :: String.t()
```

The verbose per-mutant line: every status's `verbose_leave/1` label (coloured when
`color?`), the shared descriptor, and a duration suffix for a mutant that actually ran
(`duration_ms > 0` — so a no-coverage/ignored/poisoned mutant, which launched no suite,
shows no time).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
