Agent mode

What --agent changes, the envelope it returns, and the guarantees it makes.

9 sections4 min read

--agent is a flag on every command, not a separate protocol. There is no session to open, no stdin to write to, and no state between calls.

Any commandbash
cf status --agent
cf reproduced --repo acme/api --severity critical,high --agent
cf fix generate <finding-id> --wait --agent

What it changes

  • Implies --json, --no-color, and --no-link.
  • Forces non-interactive, so nothing can ever stop to ask.
  • Silences all progress output.
  • Prints exactly one line of JSON on stdout, success or failure.
  • Does not imply --yes. Publishing and merging still refuse without it.

The success envelope

stdoutjson
{
  "schemaVersion": 1,
  "ok": true,
  "command": "reproduced",
  "data": {
    "repository": "acme/api",
    "total": 32,
    "counts": { "critical": 5, "high": 14 },
    "findings": []
  },
  "next": [
    "cf reproduced show <id> --repo acme/api --agent",
    "cf fix generate <id> --wait --agent"
  ]
}
schemaVersionnumberrequired
The envelope version. Currently 1.
okbooleanrequired
Whether the command succeeded. Branch on this first.
commandstringrequired
Which command produced this, as a space separated path such as fix publish.
dataobject
The result. Its shape depends on the command. See Agent commands.
nextstring[]
Real commands that act on what was just returned, computed from the state actually fetched. Prefer them over commands you compose yourself.

The error envelope

stdout, not stderrjson
{
  "schemaVersion": 1,
  "ok": false,
  "command": "fix publish",
  "error": {
    "code": "confirmation_required",
    "message": "Publishing opens a real pull request on GitHub.",
    "remedy": "Pass --yes to confirm: cf fix publish <id> --yes",
    "exitCode": 2
  }
}

Guarantees

  • One JSON object per invocation, on stdout. Success and failure both.
  • Human text never appears on stdout in agent mode. There is nothing to strip.
  • Every error is structured, including unexpected ones, which arrive as internal_error.
  • Never interactive. Anything that would have prompted fails with a code instead of hanging.
  • No memory between calls. --agent implies --no-link, so it deliberately remembers no default for the working directory.

Always pass --repo

Name the organization too

An organization is the shared workspace for a team. Every repository, connected account, and finding belongs to one, so every request has to say which team it is for. Four things can say it, and the first one that does wins.

OrderSource
1--org <slug> on the command
2CEFENSE_ORG in the environment
3The selection cf org use <slug> stored on this machine
4Nothing, and the API picks

The fourth works only when the account belongs to exactly one organization. If it belongs to several and the command names none, the API answers organization_required with exit code 2 instead of guessing, because guessing would mean reading another team's findings and saying nothing about it.

Find out which one, then say sobash
cf org list --agent
cf org show --agent
cf reproduced --repo acme/api --org acme --agent

What your role lets you run

The account you are signed in as holds one of three roles in the organization: owner, admin, or member. cf org list --agent reports which. A member can scan, read findings, triage them, and generate patches. A member cannot connect or disconnect a repository or a provider account, manage registry connections, publish or merge a fix, or attest a proof.

Exit codes

CodeMeaning
0Success.
1Findings present, with --exit-code.
2Usage error, including a refused confirmation.
3Not signed in.
4The API failed, or the scan failed.
130Interrupted.

Signing in

Have a correction or need help?

Email the docs team