CLI

Scripting

Drive the Polylane CLI from shell scripts, CI jobs, and coding agents with JSON output, stable exit codes, and non-interactive mode.

The CLI is built to be driven by scripts and coding agents. Data goes to stdout, everything else goes to stderr, exit codes are stable, and every prompt can be disabled.

Output format

Output is text when stdout is a terminal and JSON when it is piped or redirected. Force a format with --output json (or --output text), the POLYLANE_OUTPUT environment variable, or the config file. Precedence: flag, then environment variable, then config file, then terminal detection.

The stream contract:

  • stdout carries pure data: JSON, table rows, streamed tokens. Safe to pipe.
  • stderr carries spinners, progress, hints, and error messages.
Terminal
polylane issue list --output json | jq '.items | length'
polylane issue list --quiet 2>/dev/null

Non-interactive mode

Pass --non-interactive to fail fast instead of prompting for missing input. polylane cloud disconnect refuses to run in non-interactive mode unless you also pass --yes. Other confirmations, such as polylane memory delete, are skipped in non-interactive mode, so pass --yes explicitly to make intent clear.

The flags you combine most often in scripts:

FlagPurpose
--output jsonForce JSON regardless of terminal state
--quietSuppress spinners and progress; stdout stays pure data
--non-interactiveFail fast on missing input instead of prompting
--yesSkip confirmation on destructive commands
--dry-runShow what would happen without making changes
--fullReturn full objects on list commands instead of the narrow field projection
--api-key <key>Override the stored API key for one call
--workspace <id>Override the default workspace for one call

POLYLANE_API_KEY and POLYLANE_WORKSPACE_ID set credentials and workspace from the environment, which suits continuous integration jobs. See Configuration and Authentication.

Worked example: list issues as JSON

polylane issue list returns { "items": [...], "count": n }. By default each item is projected to id, severity, status, title, resourceKind, resourceId, detectedAt, and investigationThreadId.

Terminal
polylane issue list --active --severity critical --output json --quiet \
  | jq -r '.items[] | "\(.id)\t\(.title)"'

Pass --full for the complete objects. See Issues for the lifecycle behind each status.

Worked example: trigger a thread from a script

polylane thread ask starts a thread and blocks until the agent replies. With --no-wait it returns immediately with { "id", "name", "status": "accepted" }, so you can fire it off and poll later.

Terminal
TID=$(polylane thread ask "which services deployed in the last 24 hours?" \
  --no-wait --output json --quiet | jq -r '.id')

polylane thread show "$TID" --output json | jq '.messages.items[-1]'

Use --stream instead to stream the reply tokens to stdout as they arrive; streaming requires an OAuth login. Attach context by ID with --context repo_xxx,acc_yyy; the CLI infers each resource type from the ID prefix.

Exit codes

Branch on $? to decide whether to retry, re-authenticate, or surface the failure.

CodeMeaning
0Success
1General error
2Usage error: bad flag, missing argument
3Authentication error
4Rate limit or plan upgrade required
5Timeout
6Network error
130Interrupted with Ctrl-C

Error envelope

Errors always go to stderr, so piped stdout stays parseable. In JSON mode the shape is:

{
  "error": {
    "code": 3,
    "message": "Unauthorized - check your API key",
    "hint": "Run `polylane auth login`"
  }
}

code matches the process exit code. hint, when present, tells you how to fix the problem. Branch on the exit code first, then parse the envelope for detail.