Reading the output

How the CLI lays out a list, where it pages, and the few places it stops to ask you something.

7 sections4 min read

The CLI is not a full-screen application. Commands print, you read, and you run the next command. This page is how that output is laid out, and where the CLI does stop to ask.

Three output modes

ModeHow you get itWhat comes out
Agent--agent, or CEFENSE_AGENT in the environmentExactly one line of JSON on stdout, success or failure. Never interactive.
JSON--jsonThe API response, pretty printed. No envelope.
Renderedthe defaultColoured tables for a terminal, and tab separated lines when piped or redirected.

Agent mode wins over --json, and --json wins over rendering. Full detail in JSON output and Agent mode.

Grouped lists

cf reproduced and cf matched group findings by severity, worst group first. cf fix groups the same findings by the state of their patch, and cf proof groups them by verdict. Each group carries a heading and its own rows, which is what lets you read the Critical block and stop.

cf reproduced
cf reproducedShowing 12 of 31 findings in acme/apiCritical  a1f3c2  src/routes/report.ts:48  Server-side request forgery   no patchHigh  9b02de  src/db/users.ts:112      SQL injection                readyUse --limit 31 to see them allcf reproduced show a1f3c2

Under the rows, a count line says how many of the total you are looking at, a footnote tells you when the list was truncated, and a short next steps block names the commands that act on what you just read. Those are real commands with the ids filled in, so they can be copied rather than composed.

cf status, cf branches, cf commits, and cf audit print a flat table instead, because there is nothing meaningful to group them by.

Choosing the columns

Narrow the tablebash
cf reproduced --columns id,title
cf commits --columns commit,delta,when

--columns takes a comma separated list and reorders the table to the order you name, so it is both a filter and an ordering. A name the view does not have is refused with unknown_column, which lists the ones it does have. It applies to the rendered table only: a piped command has its own fixed column set.

--fields is the agent-mode equivalent. It trims every list inside the JSON envelope down to the keys you name, and always keeps id so the result stays addressable.

The pager

One view is long enough to page: the full finding from cf reproduced show. When it does not fit the terminal, it opens in your pager. --no-pager prints it straight through, and so does piping, redirecting, --json, and --agent.

The pager is whatever CEFENSE_PAGER names, then PAGER, and a sensible default otherwise. Setting either to cat turns paging off everywhere without passing a flag.

Opening the same thing in a browser

--webbash
cf reproduced show <finding-id> --web
cf fix show <finding-id> --web
cf plan --web

--web opens the page a result points at rather than printing it: the file on your provider for a finding, the pull request for a patch, the plan page for cf plan. A command with no page behind it answers no_web_url rather than opening something arbitrary.

Where the CLI asks

There is no navigable screen anywhere in the CLI. What there is, in a handful of places, is a prompt: a list to choose from, a set of checkboxes, a yes or no, or a name to type out.

CommandWhat it asks
cf repo connectWhich host, when several are connected, then which repositories to connect.
cf repo set-defaultWhich repository this directory means, and whether to remember it.
cf repo disconnectWhich repository, then the repository's full name typed out.
cf provider disconnectThe connected account's login, typed out.
cf settings mode|every|depthThe value, when you give none. Choosing scheduled asks for the interval next.
cf settings checksCheckboxes, pre-ticked with the set the repository has now.
cf fix mergeWhich open pull request, when there is more than one.
cf fix publishThe repository's full name, typed out, before anything is opened.
cf proof attestConfirmation that you really did rotate the credential.
cf proof env setThe value, masked, and confirmation before replacing one already stored.
cf proof env unsetConfirmation before the value is deleted.

When there is nothing to prompt in

Piped, redirected, under --json, or under --agent, a command that would have asked fails with exit code 2 and names the flag that would have answered it instead. Nothing hangs waiting for input that is never coming.

Have a correction or need help?

Email the docs team