Skip to content

CLI reference

The CLI runs the same review engine contract as the GitHub Action. It is a reproduction and inspection tool; its output is never CI trust evidence.

diffowl review --input <pull-request.json> --policy <local-policy.json> [options]

From a repository clone:

Terminal window
npm install
npm run build
node dist/cli.js review \
--input pull-request.json \
--policy .diffowl.json \
--state-directory .diffowl-state
Option Required Meaning
--input <path> yes Path to the pull-request input JSON.
--policy <path> yes Path to a local project-policy JSON file.
--state-directory <path> no Persist and inspect local run records and finding-ledger state.
--dry-run no Run locally without publishing. This is the default.
--publish no Request publishing mode; the local_cli trust class still denies publication.
--repository <path> no Checkout at the pull-request head. Roles run inside it and may read files; the verifier may run policy validation commands there. Omit for a diff-only review.
--credentials <local|env> no Credential source for the default profile. local (default) reads the local agent directory; env reads *_API_KEY and *_BASE_URL variables.

Unknown arguments and missing option values print usage on stderr and exit with code 2.

--repository runs the roles as the invoking user in a host sandbox that restricts file paths but not the shell. Only use it on pull requests you have read; see the trust model.

Manages the shared credential store used by the Action for subscription logins. Reads DIFFOWL_CREDENTIAL_STORE_URL and, optionally, DIFFOWL_CREDENTIAL_STORE_SECRET from the environment.

Command Meaning
credentials sql Print the CREATE TABLE statement. Run it with a role that has DDL; the runner role should not.
credentials push --provider <id> [--key <row>] [--agent-dir <p>] Copy the named provider entries from the local agent auth file into the row. Nothing is printed.
credentials status [--key <row>] List provider ids and token expiry in the row, without token material.

See the credentials guide for setup.

Code Meaning
0 The engine produced a typed outcome. This includes non-clean outcomes like findings or timeout.
1 The review threw: unreadable files, invalid policy JSON path, or an engine error.
2 Argument errors or pull-request input that does not match the required schema.

The exit code reflects whether a typed outcome was produced, not whether the review was clean. Read outcome.type from the report to branch on the result.

pull-request.json
{
"repository": "example/review-target",
"number": 42,
"baseSha": "1111111111111111111111111111111111111111",
"headSha": "2222222222222222222222222222222222222222",
"diff": "diff --git ..."
}
Field Type Constraint
repository string owner/name form.
number integer Pull-request number.
baseSha string Base revision the diff applies against.
headSha string Head revision under review.
diff string Unified diff of the change.

Capture a real diff with:

Terminal window
git diff --no-color <base-sha>...<head-sha>

The CLI writes one JSON document to stdout:

{
"adapter": "local_cli",
"mode": "dry-run",
"ciTrusted": false,
"trust": { "class": "local_cli", "capabilities": { "publishing": "denied" } },
"publishing": {
"requested": false,
"status": "not_attempted",
"note": "Local CLI output is reproduction data only; it is not GitHub Action trust evidence."
},
"outcome": { "type": "findings" },
"findings": [],
"advisorySuggestions": [],
"verification": {},
"runRecord": {},
"ledger": {},
"diagnostics": {
"outcomeType": "findings",
"validationAttemptCount": 1,
"providerArtifactCount": 3
}
}
Field Present Meaning
adapter always Always local_cli.
mode always dry-run or publish.
ciTrusted always Always false.
trust always The local_cli trust classification and its capability set.
publishing always Always not_attempted; requested records whether --publish was passed.
outcome always The complete typed review outcome.
findings always Material findings from the outcome, or [].
advisorySuggestions always Advisory suggestions from the outcome, or [].
verification always Evidence catalog, validation attempts, limitations, and coverage gaps.
runRecord with state dir The persisted versioned run record for this run.
ledger with state dir The reconciled finding ledger after this run.
diagnostics always Outcome type, reason, timeout seconds, attempt and artifact counts.
Field Present Meaning
outcomeType always Mirror of outcome.type for quick filtering.
reason outcomes with a reason The typed outcome’s reason string.
timeoutSeconds timeout outcomes The exceeded hard timeout.
validationAttemptCount always Number of validation command attempts executed.
providerArtifactCount always Number of role execution artifacts captured.
ledgerEntryCount with state dir Entries in the persisted finding ledger.

Useful one-liners:

Terminal window
node dist/cli.js review --input pr.json --policy .diffowl.json | jq .diagnostics
node dist/cli.js review --input pr.json --policy .diffowl.json | jq '.findings[].summary'

Reusing the same --state-directory across runs reconciles finding lifecycle without a hosted database: a finding that persists across pushes keeps its fingerprint and moves through new, persisting, resolved, and related states.

Diffowl permission-restricts the directory, but you remain responsible for keeping it private, trusted, and backed up according to your audit requirements.

Local runs classify trust as local_cli:

  • validation commands, secrets, and tools are local_user_authorized;
  • publishing is denied, regardless of --publish.

The default credential profile is local, which resolves provider credentials through local RunCell configuration, including supported Codex or Claude logins. See Credentials and providers.