Skip to main content

Output Triple

Every CLI command in The Shift Platform supports three output modes. This pattern ensures that the same command works well for human operators in a terminal, AI agents parsing structured data, and scripts that only care about success or failure.

The Three Modes​

Human (default)​

Chalk-colored, formatted output designed for terminal readability. This is what you see when you run a command with no flags.

$ shift-cli yp services list

Services (3)

NAME OWNER SYSTEM LANGUAGE
────────────────────────────────────────────────────
auth-service platform core TypeScript
billing-api payments billing TypeScript
email-worker comms messaging Python

JSON (--json)​

Structured JSON output for agent and script consumption. All data is emitted as a single JSON object to stdout with no decorative formatting.

$ shift-cli yp services list --json
[
{
"id": "abc12345",
"name": "auth-service",
"owner": "platform",
"system": "core",
"language": "TypeScript"
},
{
"id": "def67890",
"name": "billing-api",
"owner": "payments",
"system": "billing",
"language": "TypeScript"
},
{
"id": "ghi24680",
"name": "email-worker",
"owner": "comms",
"system": "messaging",
"language": "Python"
}
]

Quiet (--quiet)​

No stdout output at all. The command communicates purely through its exit code. Useful for conditional logic in shell scripts.

$ shift-cli yp services get auth-service --quiet
$ echo $?
0

$ shift-cli yp services get nonexistent --quiet
$ echo $?
4

The output() Helper​

The output() function from @shift/platform-core/output handles mode selection. It accepts the global options and a set of handler functions:

import { output, success, table } from "@shift/platform-core/output";

output(options, {
json: () => services,
quiet: () => {},
human: () => {
success(`Services (${services.length})`);
table(services, [
{ key: "name", label: "NAME" },
{ key: "owner", label: "OWNER" },
{ key: "system", label: "SYSTEM" },
{ key: "language", label: "LANGUAGE" },
]);
},
});

The output() function checks the flags in order:

  1. If options.json is true and a json handler is provided, it serializes the return value as formatted JSON via jsonOutput().
  2. If options.quiet is true and a quiet handler is provided, it calls that handler (which typically does nothing).
  3. Otherwise, it calls the human handler.

OutputOptions Interface​

interface OutputOptions {
json?: boolean;
quiet?: boolean;
}

These flags come from Commander's global options, propagated via optsWithGlobals():

program
.option("--json", "Output as JSON")
.option("--quiet", "Suppress output, exit code only");

Additional Output Helpers​

The @shift/platform-core/output module also exports helpers used within human-mode handlers:

HelperPurpose
success(msg)Green checkmark + message
info(msg)Blue info icon + message
warn(msg)Yellow warning icon + message
error(msg)Red cross + message
bold(s)Bold text
dim(s)Dimmed text
cmd(s)Cyan text (for command references)
bullet(msg)Green bullet point
header(title)Section header with spacing
table(rows, columns)Aligned table output
barChart(items)Horizontal bar chart

Why This Matters for AI Agents​

AI coding agents need to consume CLI output programmatically. The Output Triple pattern means:

  • Agents use --json to get structured data they can parse reliably, without scraping formatted terminal output.
  • Scripts use --quiet combined with exit codes for conditional control flow (if shift-cli yp services get my-service --quiet; then ...).
  • Humans get readable output by default, with no extra flags needed.

This eliminates the common problem of agents trying to parse human-formatted output with regex or string manipulation, which breaks whenever formatting changes.