onyx command is the full terminal-only user and orchestrator CLI. The companion onyx-worker command exposes the worker-safe primitive surface used by supervised agents. In normal usage, you log in once and start research from an agent with /onyx ...; the agent composes these commands into the loop. Use this reference when debugging, scripting, or understanding what the agent is doing.
Install and Version
Developer Mode
onyx command installed
while switching it between the release CLI and a linked source checkout.
Login
--api-url (not production, not localhost) prints the
API URL, issuer, and client ID, explains that the server receives your access
and ID tokens and, for device login, also your refresh token, and asks for
confirmation; use --trust-api-url in non-interactive shells.
If a request fails with cli_session_revoked or cli_session_invalid, the CLI
removes the stored login and asks you to run onyx login. A 503 from the API
while the identity provider is unreachable is retried and never removes a
login. Older config files are migrated by onyx login, which leaves a
sanitized backup (no keys or tokens) beside the config.
Agent Skill
skill-path prints the bundled skill location. install-skill copies it into
the managed Claude Code, Codex, and OpenCode skill directories by default:
~/.claude/skills/onyx/SKILL.md, ~/.agents/skills/onyx/SKILL.md,
${CODEX_HOME:-~/.codex}/skills/onyx/SKILL.md, and
~/.config/opencode/skills/onyx/SKILL.md. Pass --dir only when you need to
install one custom skill root instead.
Profiles
onyx profile list shows each profile’s credential
store and worker defaults. Profiles can also store default worker agent/model
choices used by onyx research run and onyx worker run.
Analytics preference
ONYX_TELEMETRY_DISABLED=1 and
DO_NOT_TRACK=1 always disable collection. Analytics is disabled in workers,
CI, testbed environments, source/developer builds, and non-production API
profiles. See CLI analytics and privacy for the exact
data contract.
Worker CLI
onyx-worker is the explicit worker-safe command surface. It includes only
primitives such as research brief, research session-state-brief,
research finish, exp run, exp log, exp list, workflow status,
tools run, knowledge add, and knowledge list. It excludes
login/profile/developer, campaign/setup, research orchestration, worker
launching, public push, and removed research sync commands.
Humans and orchestrators can run onyx-worker directly for local debugging. A
supervised worker starts in the project root and receives an isolated
ONYX_HOME, an ONYX_WORKER_CONTEXT file carrying its identity and one
short-lived scoped credential, isolated temp directories, and a wrapper named
onyx-worker placed first on PATH. In that runtime, onyx-worker defaults
commands to the assigned campaign, session, hypothesis, and worker from the
context file (no identity flags needed), rejects conflicting identity or
target overrides, and re-execs the pinned wrapper if a different onyx-worker
install is resolved first. The full onyx CLI refuses operational commands
when worker context is present and points back to onyx-worker.
Campaigns
onyx/setup.json, resolving the repository remote from origin, and writing
remote campaign state through /api/v1. When GitHub access is available, Onyx
creates or reuses the internal project automatically. The Onyx orchestrator
usually runs this for you after interpreting your /onyx prompt.
The campaign’s metric name, unit, and direction are immutable. A same-name
campaign with a different metric contract is rejected; create a new campaign
instead. The command may record the current git HEAD as creation provenance,
but a campaign has no mutable base commit or shared research-history branch.
The onyx/ setup surface must be committed before this command runs.
use selects an existing remote campaign for direct one-agent mode and updates
the small local state cache. status prints the active campaign and cached
profile/project pointers.
Setup and Tools
onyx setup init creates onyx/setup.json, onyx/validation.json,
onyx/onyx.md, and onyx/tools/evaluation/run.sh. The scaffold is minimal and
does not infer editable scope, source files, or evaluation behavior from the
repository. --editable-scope and --eval-command write exactly the values you
provide. Without --eval-command, the scaffolded evaluation tool exits nonzero
until the orchestrator replaces it with a real eval that emits exactly one
primary metric line such as METRIC score=0.42.
The required metric tool declares non-empty fingerprintPaths; the scaffold
defaults to ["onyx/tools/evaluation"]. Onyx expands committed tracked files
under those paths and hashes their git contents together with the normalized
metric and tool configuration. Missing, untracked, escaping, or symlinked
inputs fail validation. A changed evaluation fingerprint creates a separate
evaluation revision, so incomparable results never share one leaderboard.
onyx setup validate runs static local checks and writes
onyx/validation.json. It checks schema shape, setup hash, project path,
workflow/tool/resource references, a leading agent step, one required metric
step, referenced tool files, protected setup paths, and nontrivial narrative
context. Warnings for missing safety/readiness/reliability-style steps do not
block Research.
onyx-worker tools run executes a declared tool from onyx/setup.json with declared
cwd/env, timeouts, output capture, and local resource slot leases. It is for
manual diagnostics only: it never creates workflow state and never creates a
measured attempt. Operators can also reach this primitive through the full
onyx CLI.
Experiments
onyx-worker exp run owns one workflow run: one experiment attempt, one result commit,
and one primary metric. In worker context, a new run can infer the clean current
HEAD as the base, pause at the leading agent step, and later resume with
onyx-worker exp run --resume --auto without copying workflow IDs. Command steps
execute declared setup tools, capture step logs under
.git/onyx/workflow-runs/<workflowRunId>/, and create transient pending-report
outbox entries for succeeded, failed, checks_failed, or setup_violation
outcomes. These entries provide delivery and teardown safety, not research history,
and successful reporting clears them.
onyx-worker workflow status is read-only. It shows the run status, next step, block
reason, step summaries, metric snapshot, run ref, result commit, and log paths.
With --campaign, it defaults to the latest workflow run for that campaign,
including terminal runs after completion. Add --active to restrict the lookup
to running or paused runs, or --blocked for blocked runs. In worker
context, status lookups are scoped to the current worker. --run remains an
exact lookup.
/api/v1/research/worker/experiments data plane for a
supervised worker. The API returns
recorded or duplicate; recorded means delivery succeeded and normally
returns with received disposition. Workers do not wait for acceptance. Server
settlement later assigns accepted/discarded disposition and any accepted index.
Failed unmeasured attempts require
--status failed --allow-unmeasured. Protected path or out-of-scope diffs are
reported as setup_violation.
Research Sessions
onyx research run is the normal local supervisor. Every invocation creates a
new bounded remote session; sessions are never attached to or resumed. Before
session creation, Onyx resolves the provider and worker CLI to absolute paths,
checks the worker protocol/build handshake, and performs exactly one minimal
model inference probe (custom worker commands skip only the model probe).
Managed workers run bare onyx-worker commands — the supervisor pins the
verified wrapper first on PATH, and the ONYX_WORKER_CONTEXT runtime
context is the authoritative scope: identity flags default from it,
conflicting values are rejected, and worker commands refuse to operate
outside the assigned worktree. Workers use
onyx-worker research session-state-brief --json for bounded routine
context, and onyx-worker diagnostics handshake prints version, protocol,
and capability metadata. It includes complete assigned-hypothesis guidance, concise peer and
accepted-result summaries, complete selected knowledge items, progress, and
worker-specific stop guidance. Use explicit list commands when deeper history is
needed. The
default is committed HEAD, all active campaign hypotheses, and one worker.
Use repeated --hypothesis flags to narrow membership, --base to choose the
session default, and --hypothesis-base for assignment-specific starting
commits. All refs resolve locally to immutable SHAs and must contain the same
setup hash and evaluation fingerprint. For GitHub-backed projects, push those
exact commits first; preflight identifies an invisible commit and creates no
session. A run requires --experiments,
--max-minutes, or both.
The CLI refuses a second local supervisor for the campaign unless --new is
passed. A dead cached supervisor is never resumed: its old session is ended as
supervisor_failed, identity-verified orphan processes are cleaned up, and a
fresh session is created. The supervisor keeps up to the mutable worker target
active, requests server-owned leases, refreshes the local session brief and
atomic supervisor control snapshot, sends
presence and heartbeat batches, handles assignment cancellation, and records
bounded terminal diagnostics when push or reporting fails; the worker workspace
is still discarded and is not recoverable. A bounded no-progress breaker ends
systemic replacement loops and is visible in research status and listen.
The server owns worker slots, immutable session-hypothesis assignments, report
settlement and accepted experiment order. Evaluation-revision best/count/latest
summaries are computed from indexed experiment facts. Workers remain cheap: the supervisor
keeps launching while the server grants leases. onyx-worker exp log pushes the
immutable result ref then records or deduplicates the experiment through the API.
After the CLI’s bounded reporting retry fails, a worker stops new work and exits;
teardown owns the one remaining pending-attempt delivery.
Overflow attempts are retained as discarded diagnostics and can be requested
with --disposition discarded, but do not count toward targets or rankings.
onyx worker run remains a lower-level/debug primitive. Worker startup records
the worker id, scoped-credential lease state, hypothesis id, worktree, manifest path,
worker CLI path, worker context path, raw provider log path, and readable
activity log path. research status --summary --json returns bounded
orchestrator progress and supervisor health. Detailed research status --json returns structured launch
suggestions plus terminal reason, delivery, and cleanup outcomes for debugging
disposable worker failures. onyx listen renders the same outcomes and the
no-progress breaker. onyx-worker research brief fetches a compact
campaign/session brief from the API; it prints Markdown by default and structured
data with --json.
--agent selects the coding harness. --model selects the model for that
harness; OpenCode model values must use provider/model. For new sessions,
worker settings resolve from command-line flags, then ONYX_WORKER_AGENT or
ONYX_WORKER_MODEL, then the active profile’s worker defaults, then Codex.
Existing sessions keep their recorded worker agent/model and reject conflicting
flags.
onyx research scale records an auditable capacity change. Scaling up opens
lease capacity immediately; scaling down drains naturally and never kills
running workers. Use stop instead of scaling to zero. When more than one local
session is open, stop and scale require an explicit --session.
onyx research stop writes a local stop marker before signaling only
identity-verified process groups, then records the immutable server cutoff. If
the API call fails, the CLI retains stop_pending_remote state and prints the
retry command.
Closing a hypothesis cancels its assignments and workers in every open session;
late reports are preserved as discarded with hypothesis_closed. Reopening it
makes it eligible only for future sessions. Hypotheses added while research is
running are likewise available beginning with the next session.
Recovering measured reports
The supervisor retries report and cleanup-receipt delivery at startup, every 30 seconds, and during finalization. Periodic delivery does not reconcile runtimes or terminate orphan processes; runtime reconciliation is a startup check or an explicitresearch recover --runtime operation.
Without a supervisor, run onyx research recover --dry-run --json to inspect pending
counts, then onyx research recover --json to deliver eligible records. Each pass is
bounded to 25 records and a five-second request budget. Credentials must match the
saved team and API origin. Conflicts and unsupported old records remain available for
inspection; recovery never reruns an experiment or changes its immutable report body.
Canonical local experiment refs keep measured commits reachable after a failed push.
research clean refuses active or pending execution state and preserves reports,
immutable refs, and cleanup receipts. Stop by session ID works without a live supervisor
or local session pointer: onyx research stop --session <id> resolves the session remotely.
Resource locks never expire under a holder. Before resetting a resource, stop all its
launchers and child processes, then inspect
onyx research locks reset --resource <name> --confirm-idle --dry-run.
Omit --dry-run only after confirming the resource is idle. Missing PIDs alone do not
establish this. Internal push and report resources are onyx-result-ref-push and
onyx-report-delivery.
Use onyx research recover --runtime [--session <id>] [--dry-run] [--json] to
reconcile interrupted local execution before bounded delivery. Dry-run does not
create runtime files, refresh credentials or change remote state. JSON keeps the
delivery summary and adds runtime.recovered, runtime.skippedActive,
runtime.blocked, and bounded session actions/reasons. Blocked runtime recovery
returns a nonzero status; pending report delivery is reported separately.
Recovery verifies site/run ownership and boot/process identity, skips healthy
supervisors, and retains artifacts when descendant termination is uncertain.
It preserves terminal refs before removing disposable worktrees and credential
homes. Explicit recovery never changes the remote session cutoff; stop an open
session explicitly. Occupied resource slots require the existing idle reset,
including onyx-runtime-reconciliation after an interrupted launch/recovery.
Malformed evidence is retained. Repeated recovery never measures scratch work or
resumes a session. Clean refuses unresolved runtime and removes worktrees through
Git before deleting logs.