Jury reads jury.config.json in the reviewed repository (the first PR for a related-PR task).
It also accepts the former cr.config.json and macr.config.json names, in that order.
Entries merge by agent name with the built-in registry. enabled: false disables an agent.
Exactly one enabled agent may have role main; it is the default judge.
The example configuration keeps Codex as judge and Claude as reviewer:
{
"agents": [
{ "name": "grok", "enabled": false },
{ "name": "droid", "enabled": false },
{ "name": "agy", "enabled": false }
]
}Reviewers used when a run names none resolve in this order: --reviewer/--jury, any enabled
agent this file gives "role": "reviewer", the default reviewers saved with jury agents jury
("reviewers" in ~/.jury/config.json), then every enabled built-in reviewer. A saved name that
this file disables, or that is no longer an agent, stops the run with an error naming the setting.
The CLI checks executable availability before starting selected reviewers. It cannot preflight provider login, credits, or quota without invoking the provider. Runtime failures stop the loop and remain visible in the saved reports.
{
"agents": [{
"name": "my-reviewer",
"role": "reviewer",
"argv": ["my-reviewer", "--prompt", "{{promptText}}"],
"cwd": "worktree",
"promptDelivery": "argv",
"report": "whole",
"expectSeconds": 300
}]
}my-reviewer is a placeholder executable, not an included product. Use arguments supported by your CLI.
Replies redact other reviewers' complete names and finding IDs from verdicts, reproduction notes,
and test explanations. Hyphens remain part of a name, including at its end; longer names and words
that merely contain that name are left intact.
Redaction processes the original text once, so names such as another, reviewer, or finding
cannot alter generated replacement phrases, and reviewer order does not change the result.
Supported prompt delivery is argv or file ({{promptFile}}); stdin is closed.
cwd: "worktree" starts in the checkout; with cwd: "flag", pass {{worktree}} in the command.
report: "tail" extracts a final response from a verbose transcript; report: "kimi-json" reads the
assistant messages out of Kimi Code's --output-format stream-json lines. report: "codex-json"
reads the final assistant message from Codex's --json events and requires a completed turn.
Use report: "whole" for CLIs that print only their response.
Reviewers have a hard 600-second (ten-minute) deadline per invocation, including replies.
Output does not reset it, and expectSeconds does not extend it. A timeout remains a failed,
incomplete review with the message Timed out after 10 minutes, partial output, and measured
elapsed time saved in the run. On Linux/macOS, Jury sends SIGTERM to the reviewer's process
group and SIGKILL after at most five seconds; Windows uses taskkill /T /F.
The judge's explicit, separate timeout budget is unchanged.
Command placeholders are {{promptText}}, {{promptFile}}, {{worktree}}, {{sessionId}} (for
resumable agents), and {{packageDir}}, the directory Code Jury is installed in, for files that ship
with it such as lib/agents/kimi-reviewer.md.
The historical YAML example is design documentation; the CLI loads JSON.
A judge may specify separate judgeArgv. A custom argv overrides the built-in judge invocation
unless you also specify judgeArgv. Optional session configuration is illustrated by the built-in
definitions in lib/agents/.
Jury can start an agent with a chosen model. The model is passed only on the command line or in
the environment of the process Jury starts; Jury never edits an agent's own configuration, so
running claude, codex and the others outside Jury keeps their normal default.
jury agents model # the model each agent starts with
jury agents model claude opus # save a default in ~/.jury/config.json
jury agents model claude --reset # back to the CLI's own default
jury review <pr-url> --model claude=sonnet --model codex=gpt-5.5 # this run onlyA repository can set one per agent in jury.config.json:
{ "agents": [{ "name": "claude", "model": "opus" }] }Precedence: --model <agent>=<model>, then model in jury.config.json, then the saved model,
then the CLI's own default. The same model is used on the first run, on resumed rounds and
replies, and when the agent judges. The run records the models it used (models in run.json),
and jury agents shows each agent's model. An agent with a configured model but no way to take
one stops the run before any agent starts rather than silently using its default.
| Agent | How the model is passed | Verified against |
|---|---|---|
codex |
--model after exec (and exec resume) |
codex-cli 0.156.1 |
claude |
--model |
Claude Code 2.1.281 |
grok |
GROK_MODEL environment variable |
grok-cli README |
opencode |
--model provider/model after run |
opencode 1.18.32 |
qwen |
--model |
qwen 0.24.4 |
copilot |
--model |
Copilot CLI 1.0.88 |
kimi |
--model, an alias defined in ~/.kimi-code/config.toml |
Kimi Code 2.1.1 |
droid |
--model after exec (droid exec --help lists the IDs) |
droid 0.226.2 |
agy |
--model (agy models lists them) |
agy 1.2.10 |
cursor |
--model (cursor-agent --list-models lists them) |
cursor-agent 2026.09.23 |
trae |
--model after exec |
traecli 0.207.1 |
amp |
not supported: --mode selects model, prompt and tools together |
— |
A built-in definition supports models by marking the flag's position with a "{{modelArgs}}"
element in every command it runs and giving modelArgs (for example ["--model", "{{model}}"]),
or by giving modelEnv. A custom agent can use {{model}} directly in its argv.
Built-in agents are data, not code: each is one JSON file in lib/agents/, listed in
lib/agents/registry.js. Adding one is a new file plus a two-line change to that list, and
touches nothing else — jury agents, --reviewer, --judge and the saved global judge all
read from the registry.
- Copy an existing definition, for example
lib/agents/qwen.json. - Add it to the import list in
lib/agents/registry.js. - Run
npm test.
lib/agent-schema.js defines every permitted field, and test/builtin-agents.test.js validates
the whole registry, so these fail in CI rather than mid-review:
- a missing or unknown field, including a missing
sandbox; - an
argvwhose prompt template never reaches the agent; - a
cwd: "flag"entry that forgets to pass{{worktree}}; - a resume that would reattach to the latest session instead of one named by
{{sessionId}}; sandbox: "none"without asandboxNoteexplaining the boundary.
Verify the flags against the agent's own --help before adding it, and record its install
command and docs URL so jury agents can tell users how to install a missing reviewer. New
agents should ship with "enabled": false so a default install needs no extra CLI.
Agents marked opt-in are not used unless named with --reviewer/--jury/--judge, or
enabled in jury.config.json. They are supported, just not conscripted by default — otherwise a
review could not start until every supported CLI was installed.
| Agent | Executable | Reviewer invocation | Judge invocation |
|---|---|---|---|
| Codex | codex |
Read-only sandbox | Workspace-write sandbox |
| Claude | claude |
Plan mode; edit tools disallowed | acceptEdits permission mode |
| Grok | grok |
--always-approve |
Same command unless overridden |
| Droid | droid |
--auto medium |
Same command unless overridden |
Antigravity (agy) |
agy |
--dangerously-skip-permissions, print mode |
Same command unless overridden |
| Qwen Code (opt-in) | qwen |
Default approval; write tools excluded, Git inspection allowed | --approval-mode yolo |
| Copilot CLI (opt-in) | copilot |
Write tools denied; read and Git inspection allowed | Tools allowed |
| OpenCode (opt-in) | opencode |
Plan agent with explicit edit/task/shell restrictions | Build agent with --auto |
| Cursor Agent (opt-in) | cursor-agent |
--force |
|
| Amp (opt-in) | amp |
Same command unless overridden | |
| Kimi Code (opt-in) | kimi |
Prompt mode with the shipped lib/agents/kimi-reviewer.md profile: Edit and Write tools removed, only the read-only explore sub-agent; shell available |
Prompt mode with all tools |
TRAE CLI (opt-in, trae) |
traecli |
exec in read-only sandbox |
exec in workspace-write sandbox |
| Custom | Your argv[0] |
Your argv |
Your judgeArgv, or argv |
jury agents prints this warning for every such
reviewer that is installed. Prefer a sandboxed agent where that distinction matters.
Each definition records this as a sandbox field (sandbox, plan, tools, or none); an
agent declaring none must also carry a sandboxNote explaining the boundary, which is what
jury agents prints.
These are Jury's configured arguments, not a guarantee about third-party behavior.
Prompts ask reviewers not to edit, but permissions vary by agent, and resumed sessions have their
own provider semantics. Only run agents and repositories you trust. --push=false controls Jury's
push step; it does not prevent an agent from executing Git or other commands.
No provider keys belong in configuration. Each CLI uses its own login/configuration and inherits your environment. Run records include prompts and outputs, so redact them before sharing.
A reviewer's reply is a turn in the conversation that raised the findings, so the agent can see what it said. Every resume names an explicit session id — never "the latest session", which would answer whatever ran most recently in that worktree rather than this review.
An id reaches Jury one of two ways. Some CLIs accept one we generate
(--session-id), so the conversation is identified before it exists. The rest
print one in structured output, which is read back with resume.idFrom or
resume.idFromEvent. Codex uses --json and
"idFromEvent": { "type": "thread.started", "field": "thread_id" } to read the
top-level provider event, separate from assistant text and tool output. An id
is never inferred from assistant prose: a model that happens to mention a UUID
is not reporting its session, and resuming on that would deliver a verdict into
an unrelated conversation.
| Agent | Session id | Resumes |
|---|---|---|
| Claude | assigned --session-id |
yes |
| Grok | assigned --session-id |
yes |
| Qwen | assigned --session-id |
yes |
| Codex | thread_id in exec --json's thread.started event |
yes |
| Droid | session_id in -o json |
yes |
| Antigravity | conversation_id in --output-format json |
yes |
| OpenCode | sessionID in the JSON event stream |
yes |
| Kimi Code | printed at the end of the stream-json output |
yes |
| Amp, Cursor, Copilot, TRAE CLI | — | no; replies start fresh with the finding context |
Agents that do not resume lose nothing in substance: buildReply quotes their
own prior findings back to them. A resumable judge keeps its own conversation across
findings and rounds, persisted separately from reviewer sessions. Explicitly selecting
--reviewer codex --judge codex uses these separate roles without an extra flag; it
provides no model diversity or guarantee of independent judgment. Initial reviews
start fresh, and replies resume only the reviewer session that produced the findings.
resume.argv is the reviewer resume command. An optional resume.judgeArgv supplies
a different command for resumed judging; otherwise the judge uses resume.argv.
Both must name {{sessionId}}, never a latest-session shortcut. Codex sets explicit
--sandbox read-only for reviewer resumes and --sandbox workspace-write for judge
resumes. Custom resume configuration replaces the built-in resume object.
-
Kimi Code: verified CLI 0.39.1 and 0.42.0 (
npm install -g @moonshot-ai/kimi-code); runkimi login, or put an API key in~/.kimi-code/config.toml, whosedefault_modelis the model used. Prompt mode (kimi -p) rejects--plan,--yoloand--autoand approves every tool call itself, so the reviewer boundary is the shipped agent profile: it wraps Kimi's default prompt, removes the Edit and Write tools, and allows only the read-onlyexploresub-agent (the defaultcodersub-agent can write). The shell stays available, so the profile is not a sandbox. The report is read from--output-format stream-json, and replies resume the exact session id Kimi prints at the end of the stream; the profile flag is omitted on resume because Kimi refuses it next to--session, and the session keeps the agent it was created with. Kimi keeps its own session history per working directory under~/.kimi-code. The legacy Pythonkimi-cliinstalls an executable of the same name but takes different flags (kimi --versionprints 1.x for it and 0.x for Kimi Code); to keep using it, override the entry injury.config.json:{ "agents": [{ "name": "kimi", "argv": ["kimi", "--quiet", "--work-dir", "{{worktree}}", "--prompt", "{{promptText}}"], "report": "whole", "resume": { "supported": false, "reason": "quiet mode prints no session id" } }] } -
TRAE CLI: verified
traecli0.206.1 (TraeCode CLI 2.0) flags; install withsh -c "$(curl -fsSL https://trae.cn/trae-cli/install_v2.sh)"(the script is served only inside mainland China; outside it, download your platform's binary from the official release manifesthttps://lf-cdn.trae.com.cn/obj/trae-com-cn/trae-cli/v2/latest.json, check itssha256, gunzip it and link it as~/.local/bin/traecli), then runtraeclionce to log in, or usetraecli login --with-trae-patfor headless machines. TraeCode CLI requires a TRAE Enterprise flagship plan. Reviews runtraecli exec --sandbox read-only, and the judge uses--sandbox workspace-write. The prompt follows--, so a prompt starting with-is never read as a flag. Replies start fresh with finding context. -
Cursor: verified
cursor-agent2025.10.28-0a91dc2; runcursor-agent login. The generic executableagentmay belong to another product, so Jury usescursor-agent. Final JSON must explicitly report success. Replies start fresh. -
Copilot: verified CLI 0.0.392 flags; authenticate with interactive
/login. A reviewer can inspect files and Git but cannot use write tools; the judge allows tools. Local permission configuration remains trusted. Replies start fresh. -
Qwen: targets CLI 0.23.4 (
npm install -g @qwen-code/qwen-code); runqwenand complete/authbefore headless use. It runs in the process worktree, not merely an added access directory. Reviews use assigned UUIDs, and replies resume only that UUID; no implicit latest session. Final JSON must explicitly report success. -
Amp: verified CLI 0.0.1788739286; run
amp login. Threads are private and IDE context is disabled. Both roles can execute tools automatically; replies start fresh with their own finding context. (--stream-jsondoes expose a thread id, so resume is possible once that output mode is parsed.)
A missing executable, nonzero exit, timeout, or unsuccessful structured result never approves a review. Git command allowlists are CLI tool permissions, not OS sandboxes; use trusted local agent configuration. Model credentials and service availability are prerequisites for live inference.