Define a CLI's output contract — human by default, --json on demand, data to stdout, diagnostics to stderr — and an exit-code map treated as a public API. Use when a tool must serve both humans and scripts, or CI keeps passing on real failures.
Scanned 9/23/2026
npx -y skills add mcorbett51090/RavenClaude --skill output-and-exit-code-contract --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Output And Exit Code Contract?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/mcorbett51090-output-and-exit-code-contract)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
name: output-and-exit-code-contract
description: "Define a CLI's output contract — human by default, --json on demand, data to stdout, diagnostics to stderr — and an exit-code map treated as a public API. Use when a tool must serve both humans and scripts, or CI keeps passing on real failures."
---
# Output & Exit-Code Contract
## Two streams, never crossed
- **stdout = the program's data/result.** This is what `tool | next` and `tool > file` consume.
- **stderr = everything else** — logs, progress, prompts, warnings, errors.
This split is what makes a tool composable: `tool 2>/dev/null` shows only data; `tool >/dev/null` shows only diagnostics.
## Two output modes, one switch
- **Human-readable by default** — formatted, possibly colored (gated, see below).
- **`--json` on demand** — emit **only** structured data on stdout, with **no human log lines interleaved**. Keep the two renderers separate so a stray log never corrupts the JSON stream.
## Exit codes are an API
| Code | Meaning |
|---|---|
| `0` | Success |
| `1` | General/unexpected error |
| `2` | Usage error (bad args/flags) |
| `3`+ | Distinct **domain** failure classes (document them) |
| `128 + N` | Killed by signal N (e.g. SIGINT → 130) |
**Never exit `0` on a real failure** — every downstream CI step trusts the code and keeps going. Print the error + a remediation hint to **stderr**, then exit a non-zero code.
## Color & TTY discipline
Gate color/progress behind **`isatty(stderr)`** *and* honor **`NO_COLOR`** (any non-empty value disables) and **`FORCE_COLOR`** (overrides a non-TTY). Emitting ANSI codes into a pipe or redirected file turns logs into escape-code soup.
## Pipe friendliness
Read **stdin** when piped (treat `-` as "read stdin" where sensible). Don't prompt interactively when stdin/stdout isn't a TTY — require a flag instead.
See the output/exit-code tree in [`../../knowledge/cli-tooling-decision-trees.md`](../../knowledge/cli-tooling-decision-trees.md).
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!