# Terminal output

> Show what a Command is doing with progress, status lines, tasks, details and lists, styled in terminals and plain in logs.

This guide covers what Commands print while they run. You will learn how to:

- Keep the result apart from progress
- Write status lines, tasks, details and lists
- Control colors
- Find a Command's output in Agent mode

## Overview

A Command prints two things. Its [result](commands.md#return-a-result), which `Run` returns, goes to stdout, so `act about | grep Mode` and scripts see only that. Everything it shows while it runs (progress, status lines, tasks) goes to stderr. In [Agent mode](../../reference/agent-mode.md), progress goes to a log file instead, and the JSON result points to it if the Command fails.

## Write progress

`c.Progress()` is where a Command writes what it's doing. Write to it like any `io.Writer`:

```go
			fmt.Fprintln(c.Progress(), "Checking the build...")
```

Programs run with [`c.Exec`](commands.md#run-other-programs) write their output there too.

## Write status lines

`Info`, `Warn` and `Error` write a line with a colored label. `Error` is for a failure the Command continues past, such as one file of many; a failure that ends the Command is the error `Run` returns:

```go
			c.Info("Deployed version %s", "v1.4.0")
			c.Warn("The cache is cold")
			c.Error("Could not notify %s", "#deploys")
```

```text title="Output"
 INFO  Deployed version v1.4.0
 WARN  The cache is cold
 ERROR  Could not notify #deploys
```

## Run tasks

`c.Task` runs a function and writes a line for it with how long it took, and `DONE` or `FAIL`. It returns the function's error:

```go
			if err := c.Task("Running migrations", func() error {
				return c.Exec(ctx, "go", "run", "./migrate")
			}); err != nil {
				return nil, err
			}
```

```text title="Output"
  Running migrations ................................................. 1.2s DONE
```

In a terminal the title shows while the task runs, and the rest of the line follows when it finishes.

## Write details and lists

`Detail` writes a name and a value, joined by dots across the line, and `Bullets` writes a list:

```go
			c.Detail("Environment", "production")
			c.Bullets("app/controllers/posts.go", "app/views/posts.html")
```

```text title="Output"
  Environment ....................................................... production
  • app/controllers/posts.go
  • app/views/posts.html
```

Lines are as wide as the terminal, up to 120 columns, or 80 columns when the output isn't a terminal.

## Control colors

Output uses colors only when stderr is a terminal. Setting `NO_COLOR` to any value, or `TERM=dumb`, turns them off. Tinka never queries the terminal, such as for its background color, so output is instant in every terminal, over SSH and in multiplexers. Colors are the standard sixteen, readable on light and dark backgrounds.

## Read output in Agent mode

In Agent mode, progress and status lines go, as plain text, to a temporary log file. The file is deleted when the Command succeeds. When it fails, the JSON result carries the file's path and its last 50 lines:

```text title="Output"
{"command":"deploy","result":"error","error":{"code":"exec_failed","message":"`go run ./migrate` exited with status 1"},"log":"/tmp/act-1218377862.log","tail":"Checking the build...\n  Running migrations ................................................. 1.2s FAIL","duration_ms":1240}
```

See also: [Creating Commands](commands.md), [Agent mode](../../reference/agent-mode.md)
