> ## Documentation Index
> Fetch the complete documentation index at: https://runinfra.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up with your coding agent

> Paste one prompt into your coding agent. Approve sign-in and say yes to the setup plan. Your agent does the rest.

Your coding agent sets up RunInfra's open models for you.
You paste a prompt, approve sign-in, and agree to the setup plan.
Your agent runs the CLI commands and explains what comes next.

## What you do

You need a RunInfra account, a workspace you own, and credits or a serving Coding plan for one short paid check.

<Steps>
  <Step title="Paste the setup prompt">
    ```text wrap theme={"dark"}
    Set up RunInfra's open models in this coding agent for me. Read https://runinfra.ai/docs/tools-sdks/agent-setup.md and follow it step by step. If you cannot open links, run `npx -y @runinfra/cli@latest --help` and follow its FOR CODING AGENTS section. I approve sign-in in my browser. Before you install anything, change this agent's settings or spend money, show me the plan and wait for my yes.
    ```

    Paste it into the coding agent you want to connect, in a mode that can run commands.
    Your agent reads this page and checks the RunInfra CLI.
    It asks before installing or updating it, and it may ask your permission before each command.
  </Step>

  <Step title="Approve sign-in">
    Your agent shows you a link, [https://runinfra.ai/cli/authorize](https://runinfra.ai/cli/authorize), and a code such as `ABCD-EFGH`.
    Open the link and sign in. Type the code and select **Continue**.
    The next page shows the code again and the workspace it will connect.
    It uses your active workspace; to use another workspace you own, switch to it in RunInfra and reload the page.
    Select **Approve** only if the code is the one your agent just showed you and you asked for this setup.
    Otherwise select **Deny**. Never enter a code someone sent you.
    Only a workspace owner can approve. If the page says **No eligible workspace**, ask an owner to run the setup.
    When the page says **Done**, tell your agent you approved. The code works for 15 minutes.
  </Step>

  <Step title="Say yes to the setup plan">
    If a Coding plan can pay, your agent first asks whether to use it or Pay as you go.
    Then it shows the setup plan: the files it will change, any new or revoked RunInfra key, one short paid check (a small test request billed like any other), and who pays.
    Coding plan uses the plan first, then credits under your workspace policy. Pay as you go uses workspace credits only.
    Without a plan, the new key pays from credits and can use a Coding plan you add later.
    The workspace can appear only as an ID; it is the one you approved in the browser.
    Say yes only if you agree.
  </Step>
</Steps>

When setup finishes, your agent tells you how to start: a command to run, a model to pick, or an app to restart.
Until you do that, your current chat keeps using your earlier provider.

## What your agent does

Your agent identifies itself, signs in with your approval, and asks the CLI for a setup plan.
After your yes, the CLI creates or reuses a RunInfra key for that agent, writes the reviewed settings, and sends the paid check.
Your agent then gives you the start, model choice, and restart instructions.
You never need to paste an API key into the conversation.

## Supported agents

These agents have individual guides.
The table shows how a new setup connects.
Earlier connections keep their existing settings and command.

| Agent | Command ID | How it connects | Guide |
| - | - | - | - |
| Claude Code | `claude` | Separate command | [Claude Code](/docs/tools-sdks/claude-code) |
| Codex | `codex` | Separate command | [Codex](/docs/tools-sdks/codex) |
| OpenCode | `opencode` | Next to your provider | [OpenCode](/docs/tools-sdks/opencode) |
| Pi | `pi` | Separate command | [Pi](/docs/tools-sdks/pi) |
| Aider | `aider` | Becomes the agent's provider | [Aider](/docs/tools-sdks/aider) |
| Qwen Code | `qwen-code` | Next to your provider | [Qwen Code](/docs/tools-sdks/qwen-code) |
| Kilo Code | `kilo-code` | Next to your provider | [Kilo Code](/docs/tools-sdks/kilo-code) |
| Goose | `goose` | Next to your provider; you finish a key step yourself | [Goose](/docs/tools-sdks/goose) |
| Continue | `continue` | Next to your provider | [Continue](/docs/tools-sdks/continue) |
| Cline | `cline` | Becomes the agent's provider | [Cline](/docs/tools-sdks/cline) |
| Droid | `droid` | Next to your provider | [Droid](/docs/tools-sdks/droid) |
| Zed | `zed` | Next to your provider; preview; you finish a key step yourself | [Zed](/docs/tools-sdks/zed) |
| Grok Build | `grok` | Separate command | [Grok Build](/docs/tools-sdks/grok-build) |
| Hermes | `hermes` | Separate command | [Hermes](/docs/tools-sdks/hermes) |
| OpenClaw | `openclaw` | Separate command | [OpenClaw](/docs/tools-sdks/openclaw) |
| Crush | `crush` | Next to your provider | [Crush](/docs/tools-sdks/crush) |

Using another agent? Check the [full list](#3-identify-yourself).
RightNow Agent has [its own setup guide](/docs/tools-sdks/rightnow).
Cursor, Warp, Trae, JetBrains AI Assistant, Twinny, Fx and dsh need manual setup: create a key in [API keys](https://runinfra.ai/settings/api-keys) and enter it with the base URL `https://api.runinfra.ai/v1` in that agent's own model settings, never in a chat.
See the [Model APIs quickstart](/docs/api-reference/model-apis-quickstart).

## Undo

Ask your agent to disconnect RunInfra. It shows you what it will restore and waits for your yes.
Disconnect also revokes the RunInfra key it made for that agent.

* **Separate command**, such as `claude-run`: disconnect deletes that command's folder, including its sessions and history. Copy anything you need first, and ask in your usual agent, not inside `claude-run`.
* **Next to your provider**: disconnect removes what RunInfra added and keeps your other providers.
* **Became the agent's provider**: disconnect restores your earlier settings.

Disconnect does not sign this computer out.
To do that, ask your agent to review `runinfra logout --json`, or revoke it under **Terminal sessions** in [Settings > API keys](https://runinfra.ai/settings/api-keys).

That is all you need. The rest of this page is for your coding agent.

## Instructions for coding agents

If your fetch tool summarized this page, download it with your shell, for example `curl -fsSL https://runinfra.ai/docs/tools-sdks/agent-setup.md`, and read it in full from stdout without saving a file.
Each docs page has a Markdown version at the same URL with `.md` appended.
These instructions and examples describe CLI 0.4.1; use 0.4.1 or later.

Quick path, with details in the numbered steps below:

1. `runinfra --version --json`; ask before installing or updating.
2. `runinfra whoami --json`; if needed, start `runinfra login --device --no-wait --json` without asking first.
3. Relay the code and stop for the human's browser approval; then `runinfra login --device --json --timeout 100`.
4. `runinfra agents --json`; identify only yourself.
5. `runinfra plan --json`; if a Coding plan can pay, stop for the human's payer choice before review.
6. `runinfra connect <id> --json`, adding `--funding plan` or `--funding credits` only for the human's choice when a Coding plan can pay; show all changes and the stderr payer line, then stop for yes.
7. `runinfra connect <id> --json --yes`, keeping any reviewed `--funding` and `--preview` exactly; hand off to an outside terminal if your app must close.
8. Relay the launcher path, model choice and restart; `runinfra doctor --json`, reading your connection's row.
9. Only when asked: `runinfra disconnect <id> --json`; show restoration, key revocations and profile deletion before yes.
10. Never handle keys, read private files, save output, choose a serving plan's payer yourself, approve in a browser, start an interactive agent, or retry a failed apply directly.

Follow these rules before executing the numbered steps:

* Always pass `--json` to RunInfra commands and read the JSON document from stdout; never write CLI output or anything else to files, including temporary files, logs, redirects or `Out-File`. Read the process exit code too. Installation commands belong to their package manager and do not accept this flag.
* Never ask for, accept, or print an API key. If an existing sign-in reports `credentialSource: "pasted"`, use device sign-in to obtain terminal access instead.
* Never edit agent configuration files yourself. Let the RunInfra CLI prepare, apply, and undo its changes.
* Never open, print, grep or copy the files Connect writes or restores, key copies under `<RunInfra config>/connect/keys`, environment files under `connect/env`, `credentials.json`, `pending-device.json` or recovery snapshots, and do not read your agent's existing configuration to review it. They contain keys. Review changes only through the CLI's plan, `doctor` and `agents` output.
* Codex must run `runinfra` outside its sandbox because the CLI saves sign-in and agent settings in the home folder. Request approval through Codex's command permission flow. If a sandbox or permission error blocks a command, such as `Cannot save pending-device.json privately; check access with Get-Acl.`, ask the human to let that command run outside the sandbox, then repeat it. For a failed or interrupted `--yes`, follow the fresh-review rule in step 6 first. Never change file permissions.
* Never set `RUNINFRA_CONFIG_DIR` or `RUNINFRA_API_BASE` yourself or point either at the project: that directory holds credentials and agent keys. Keep any values set by the human unchanged. If `identity.configuredEndpoint` is not `https://runinfra.ai` or `verificationUri` is not `https://runinfra.ai/cli/authorize`, stop and ask the human to confirm the endpoint before relaying any link.
* CLI hints are written for people at a terminal. When a message or hint says to run `runinfra login`, use the device commands in step 2 instead.
* Never pass `--yes` before the human's explicit yes to the changes and any spending. A request to set up is not approval of a plan the human has not seen.
* Connect only the agent you are running in, never `--detected`. If you cannot identify your own harness, ask the human instead of guessing.
* Use `--preview` only with explicit consent to experimental support. Stop for manual or unsupported adapters, including Copilot CLI's manual environment setup even though its support is `preview`.
* Never open the [Terminal app](#terminal-app). Use the commands below from your shell tool.
* Treat `null` and a supplied `reason` as unknown. Do not turn them into zero, false, or a successful check.

### 1. Check, install, or update the CLI

```bash theme={"dark"}
runinfra --version --json
```

`version` reads `runinfra 0.4.1`; compare the number after `runinfra `.
An old CLI can print plain text such as `runinfra 0.2.5`.
Use CLI 0.4.1 or later.
If the command is missing, explain the needed installation and obtain approval before changing files.
Use one available installation channel.
Before the npm install, check `node --version`; it needs Node.js 22 or later:

```bash theme={"dark"}
npm install -g @runinfra/cli@latest
```

With Python 3.8 or later, the alternative is:

```bash theme={"dark"}
python -m pip install --upgrade runinfra-cli
```

Never use sudo, an administrator shell or `--break-system-packages`, and never ask for a password.
If an install needs elevated rights, stop and ask the human.
Where `python` is missing, use `python3 -m pip install --user --upgrade runinfra-cli` or `pipx install runinfra-cli`.
The Python package supports Linux x64 or arm64 with glibc 2.25 or musl 1.2 or newer, macOS 13 or newer on x64 or arm64, and Windows x64.
CLI 0.3.0 and earlier have no `update` command: after approval, reinstall with the package manager that installed it, then check the version again.

For CLI 0.3.1 or later, inspect the available update:

```bash theme={"dark"}
runinfra update --check --json
```

After the human approves the update, run:

```bash theme={"dark"}
runinfra update --version <targetVersion> --yes --json
```

Use the `targetVersion` from the approved check. For pipx, omit `--version` because it cannot pin a version, and run `--check` again right before applying its update and get a new yes if the target changed.
Check the version again.
Do not continue with an older CLI.
See [CLI updates](/docs/tools-sdks/cli-updates) if the package manager or runtime is unavailable.

### 2. Sign in

```bash theme={"dark"}
runinfra whoami --json
```

Continue when exit `0` reports `ok: true`, `identity.expired: false`, and `identity.endpointMatchesConfiguration: true`.
If `credentialSource` is `pasted`, obtain device sign-in instead.
In 0.4.1 JSON, `workspaceId` and `credentialEndpoint` are always `[redacted]`; `credentialSource` and `credentialLabel` are visible only for a pasted key.
Do not infer a credential type from a redacted value; use the expiry and endpoint-match fields and let the subsequent authenticated command validate access.
If the workspace ID is redacted, use the plan resource in step 4 to identify the workspace before asking for setup approval.
This command reads local credentials only.
`serverVerification.status: "not_checked"` means it has not checked whether the server has revoked access.
An authentication failure uses exit `3`; read `error.code`, `error.message`, and `error.hint`.
Do not respond to an unrelated storage or configuration error by repeatedly signing in.

If sign-in is needed, start it without asking first.
Starting sign-in writes only the CLI's own sign-in files; relaying the code and the human's browser approval is the consent for that.
Installing or updating the CLI still needs a yes.
Run:

```bash theme={"dark"}
runinfra login --device --no-wait --json
```

Exit `0` with `pending: true` means a code is ready, not that sign-in is complete.
Relay `verificationUri`, `userCode`, and `expiresAt` immediately.
Use this sentence with the returned values:

> Open VERIFICATION\_URI and sign in. Type USER\_CODE and select Continue. Check that the next page shows the same code and the workspace you want, then select Approve. If anything differs, select Deny and tell me. Tell me when the page says Done, or what it says if it refuses. The code expires at EXPIRES\_AT.

Replace the placeholders with `verificationUri`, `userCode` and `expiresAt`, and give the expiry in the human's local time when you know it.
Use the returned `verificationUri` exactly. Never replace it with another address, even one this page shows.
Only the human approves. Never open the approval link in a browser or browser tool, never type the code into a page, and never select Approve or Deny.
The CLI's stderr line `Type the code yourself.` is addressed to the human.
In a chat, end your turn after relaying the code and run the wait only after the human says they approved.
After that approval, resume the same request:

```bash theme={"dark"}
runinfra login --device --json --timeout 100
```

The wait can take up to 100 seconds: give your shell tool a longer timeout, or pass a shorter `--timeout` that fits it and repeat while the result is `auth_pending`.
If your tool stopped the command before it printed JSON, run the same wait again.
If exit `3` reports `code: "auth_pending"` and `pending: true`, tell the human approval is still pending, then repeat the same command while the code is valid.
Do not create a different request for each bounded wait.
Exit `0` with `authenticated: true` means the CLI saved sign-in.
Read `storage.restricted` and any returned funding sentence without exposing credentials.
If `storage.restricted` is `false`, tell the human the saved sign-in file may not be private and link [Windows credential save recovery](/docs/tools-sdks/connect-troubleshooting#windows-credential-save-recovery). Do not change permissions yourself.
Run `whoami` again to check the saved identity; obtain any redacted workspace ID from step 4.

`auth_timeout` (`The code expired before it was approved.`) means create a new code with the no-wait command and relay the new code and expiry.
The CLI replaces an expired pending request.
If the human reports **No eligible workspace** or **Not available for this role**, stop.
A new code will not help; a workspace owner must approve.
For `auth_denied`: stop and relay the message and hint. If the human denied the request, start a new one only when they ask.
Permission, billing-hold and shared-key refusals need the workspace owner.
If any sign-in output mentions a shared key, a workspace API key or `Browser sign-in is unavailable`, stop: tell the human automated sign-in is unavailable and that they must not paste a key into this conversation. Never pipe a key into `runinfra`.
Keep the same user account, home directory, and CLI configuration directory across commands so the pending request can be resumed.
Never combine `--no-wait` with `--timeout`.

### 3. Identify yourself

```bash theme={"dark"}
runinfra agents --json
```

Find your own row by `agents[].agent` using this table.
Read `displayName`, `support`, `installed`, `binaryPath`, `configDirs`, `version`, `foundBy`, `status`, `reason`, and `mode`.
`support` is `ready`, `preview`, or `manual`.
`status` is `found`, `not-found`, `timed-out`, or `error`.
`foundBy` is `binary`, `config`, `extension`, or `null`.
In the CLI document, `installed` is `false` for configuration-only detection and `null` for a failed or timed-out check.
Explain missing installation or detection failures before continuing.

`mode` is a legacy profile-capability hint in 0.4.1.
OpenCode, Qwen Code, and Nanocoder can report `profile` even though a new connection goes next to the provider.
Use `plan[].profile` and the successful result's `nextSteps[].placement` for the actual connection.

| Harness | CLI ID | Support | New connection |
| - | - | - | - |
| Claude Code | `claude` | ready | Separate command |
| Codex | `codex` | ready | Separate command |
| OpenCode | `opencode` | ready | Next to your provider |
| Pi | `pi` | ready | Separate command |
| Aider | `aider` | ready | Becomes the agent's provider |
| Qwen Code | `qwen-code` | ready | Next to your provider |
| Kilo Code | `kilo-code` | ready | Next to your provider |
| Goose | `goose` | ready | Next to your provider; you finish a key step yourself |
| Continue | `continue` | ready | Next to your provider |
| Cline | `cline` | ready | Becomes the agent's provider |
| Droid (Factory) | `droid` | ready | Next to your provider |
| Zed | `zed` | preview | Next to your provider; preview; you finish a key step yourself |
| Grok Build | `grok` | ready | Separate command |
| Hermes | `hermes` | ready | Separate command |
| OpenClaw | `openclaw` | ready | Separate command |
| Crush | `crush` | ready | Next to your provider |
| Cursor | `cursor` | manual | Manual setup; stop this procedure |
| Fx | `fx` | manual | Manual setup; stop this procedure |
| dsh | `dsh` | manual | Manual setup; stop this procedure |
| Oh My Pi | `oh-my-pi` | preview | Becomes the agent's provider |
| Kimi CLI | `kimi-cli` | ready | Separate command |
| Mistral Vibe | `mistral-vibe` | ready | Becomes the agent's provider |
| Forge | `forge` | ready | Separate command |
| gptme | `gptme` | preview | Becomes the agent's provider |
| Tabby | `tabby` | preview | Becomes the agent's provider |
| Nanocoder | `nanocoder` | ready | Next to your provider |
| Octofriend | `octofriend` | preview | Becomes the agent's provider |
| Command Code | `command-code` | preview | Becomes the agent's provider |
| Junie CLI | `junie-cli` | preview | Becomes the agent's provider |
| VS Code Copilot Chat | `vscode-copilot-chat` | preview | Next to your provider |
| Theia AI | `theia` | preview | Becomes the agent's provider |
| OpenHands CLI | `openhands` | preview | Becomes the agent's provider |
| Copilot CLI | `copilot-cli` | preview | Manual environment setup; stop this procedure |
| Warp | `warp` | manual | Manual setup; stop this procedure |
| Trae | `trae` | manual | Manual setup; stop this procedure |
| JetBrains AI Assistant | `jetbrains-ai` | manual | Manual setup; stop this procedure |
| Twinny | `twinny` | manual | Manual setup; stop this procedure |

If your harness is absent or manual, stop, explain that it has no automatic path, and point the human to the manual setup line under [Supported agents](#supported-agents).
Do not select a different agent that happens to be installed.
For a preview adapter, obtain consent and keep `--preview` on both review and apply commands.

### 4. Choose how to pay

```bash theme={"dark"}
runinfra plan --json
```

A successful read returns the bare `schema: "runinfra.cli.plan/1"` resource.
On a nonzero exit, `plan --json` returns the usual error document instead. Read `code`, `message` and `hint`, for example `not_found` (`This server does not provide coding plan information yet.`, exit `4`) or `auth_denied` (`Plan information requires terminal account access.`).
Show the plan resource's `workspace_id` to the human.
`snapshot.availability` distinguishes an available, stale, or unavailable read.
`snapshot.current: null` means there is no current plan in that read; an unavailable read does not prove there is no plan.

Offer **Coding plan** or **Pay as you go** only when the read is available, `snapshot.current.serving` is `true`, `tile_state` is neither `ended` nor `refund_closed`, and `covers` includes `chat`.
When a Coding plan can pay, you MUST ask the human which payer BEFORE running the review.
Never choose for them. Wait for their answer, even if the plan is already serving.
Read `snapshot.current.copy` when present.
Use its `policy`, `actual`, `remedy`, and `freshness` fields to explain the current limits and any refusal.
If the read is stale or unavailable, do not use it to choose a plan.
Retry the read once after a few seconds. If it is still stale or unavailable, tell the human you cannot confirm a Coding plan and offer Pay as you go or waiting.
Never choose `--funding plan` from a stale or unavailable read.
Do not infer eligibility from `sales_enabled`, a tier name, or the subscription's `status` alone.

| Choice | Argument | Tell the human |
| - | - | - |
| Coding plan | `--funding plan` | Coding plan first, then credits under your workspace policy. |
| Pay as you go | `--funding credits` | This key uses workspace credits only, even while the plan serves. |

When no plan can pay for chat, do not ask the human to choose a plan that cannot pay.
Omit `--funding`. The new key follows the workspace policy: it pays from credits now and can use a Coding plan the workspace adds later.
Disclose Pay as you go in the setup plan.
Do not add `--funding credits` on your own: that key is Credits only and keeps paying from credits after a plan is added.
Find the balance before the review: the login `funding` sentence names it, for example `Pay as you go: $250.00 in credits.`, and at $0 it ends with `Add credits in Billing before connecting.` or a frozen-account sentence.
With `--funding credits`, the review's stderr payer line repeats that balance and warning. Without `--funding`, that line states only the paid check.
With no serving plan and no credits, stop and ask the human to add credits, because approving would exit `4` (`not_entitled`) before any write.
Also stop if the human chose Pay as you go and the workspace has no credits, even when a plan could pay.
If you reused an earlier sign-in, you may not see the balance before applying; an apply at $0 exits `4` before any write, so relay its reason and ask the human to add credits.
Do not purchase a plan or add credits for the human.

An explicit choice on reconnect can change an existing key's payer with owner approval.
Show every note about that change because it affects every use of the key.
For this procedure, carry the chosen argument, or its absence, unchanged through review and apply.

### 5. Show the setup plan

If `runinfra doctor --json` already shows your connection row with `ok: true` and `link: "config"`, tell the human it is already set up and ask before reconnecting, because a reconnect sends another paid check.
Replace `<id>` with your CLI ID.
Use exactly one of these commands, matching step 4:

```bash theme={"dark"}
runinfra connect <id> --json
runinfra connect <id> --json --funding plan
runinfra connect <id> --json --funding credits
```

Use the first when no plan can pay for chat. The other two carry the human's choice when a Coding plan can pay.

Do not add `--yes` yet.
Exit `8` with `code: "consent_required"` is the expected review result.
It is not a failed connection.
A review can instead exit `6` with `code: "config_modified"`, a `refused[]` list and `plans[]` (not `plan[]`).
Nothing was written and no key was created. Relay each `refused[].reason`.
If it names `--preview`, explain experimental support and add `--preview` to both review and apply only after explicit consent.
If it says the payer is set by the workspace owner, ask an owner or keep the key's current payer.
Do not sign out, sign in again, or add `--yes` because of a refusal.
Read every entry in `plan[]` and show these fields to the human:

| Field | What to explain |
| - | - |
| `agent` | The connection being changed. A separate profile can use its command name here. |
| `files[].path` | Every file the CLI will write or restore. |
| `files[].added`, `files[].removed` | Objects with `value` and `basis`. A null value carries a `reason`; do not invent a line count. |
| `files[].preview` | When present, `value: null` and `reason` explain why a preview is unavailable. |
| `paidRequests` | The paid verification count. A normal new automatic connection sends one short request. |
| `keysCreated`, `keysRevoked` | New agent keys and keys scheduled for revocation. |
| `keyPlacement` | Where the CLI manages the key. |
| `profile` | Optional `agent`, `name`, `profileHome`, and `launcherPath` for a separate profile. |
| `notes[]` | Every note, including any visible workspace details, payer changes, model behavior, restart, and follow-up actions. Workspace text can be privacy-redacted in 0.4.1. |
| `revocations[]` | When present, each key's `id`, `keyPrefix`, and `agent`. Never substitute a full key. |
| `revokeKeyCount` | When present, a `value` and `basis` for the exact named revocations. |

In CLI 0.4.1, the payer sentence goes to stderr and is not a stdout plan field.
Read that stderr line and show its balance and any warning with the plan.
State the payer chosen in step 4 alongside the full plan.
Use this template, replacing each placeholder with the returned values:

> Setup plan for DISPLAY\_NAME in workspace WORKSPACE\_ID. Files: PATH (+ADDED/-REMOVED) for each file. Keys: creates KEYS\_CREATED, revokes KEYS\_REVOKED; the key is kept in KEY\_PLACEMENT. Paid check: PAID\_REQUESTS short request, paid by PAYER. Result: PLACEMENT\_IN\_WORDS. Notes: every note. Reply yes to apply this plan and send the paid check.

For a `slot` agent, say that RunInfra replaces the agent's current provider until you disconnect.
In 0.4.1 the workspace note always starts with `[private identifier omitted]`: give the ID in parentheses and say it is the workspace approved in the browser.
Do not invent a workspace name. If you reused a saved sign-in, say so; if the human is unsure which workspace it is, run device sign-in so they can check the name on the approval page.
For Goose and Zed, tell the human before asking for yes that the agent works only after they set `RUNINFRA_API_KEY` themselves from the key copy the plan lists.
Never open that file or print the key.
Do not silently apply when the plan contains unexpected files, workspace, key changes, or instructions you cannot satisfy.
Ask for the human's explicit yes to that plan and spending.
Wait for the answer.

### 6. Apply after yes

Repeat the reviewed command with the same ID, payer argument, and any approved preview flag, adding only `--yes`:

```bash theme={"dark"}
runinfra connect <id> --json --yes
```

Keep `--funding plan` or `--funding credits` here when the review had it.
If a plan note says to close or quit the app you are running in, do not apply from inside it.
After the human's yes, give them the exact reviewed command with `--yes` to run in a terminal outside the app after closing it, say that it sends the one paid check, and stop.
When they are back, run `runinfra doctor --json`. Disconnect works the same way.
This applies to Cline and to preview apps such as Zed, VS Code Copilot Chat, Theia AI, OpenHands CLI and Octofriend when their plan has this note.

Read `plans`, `changes`, `probes`, and `nextSteps`.
`changes.events` records what the engine did, including key, configuration, and verification outcomes.
`changes.profiles` records separate profiles.
An empty top-level `probes` array does not mean no paid check ran: connect verifies during apply and records it in `changes.events`.
Success is exit `0` with `changes.verificationFailed: false`, a `probe` event with `result.ok: true` and an `agent_done` event with `verified: true` for your connection.
Compare the returned `plans[]` with the plan the human approved; if anything differs, tell the human and list what was applied.
If `verificationFailed` is `true` (exit `4` when funding refused the check, otherwise `5`), the settings were saved but the paid check failed.
Tell the human, quote the `probe` event's `result.message` and any `retryAfterSeconds`, relay `nextSteps` as unverified, and run `runinfra doctor --json`.
For any other nonzero exit, read `code`, `reason`, `recovery` and `changes.events`.
If `missingAgents` is returned, report which work did not complete.
After any failed or interrupted `--yes` command, never repeat it directly: prepare a fresh review without `--yes`, show the new plan, and wait for a new yes.

### 7. Finish setup

Tell the human how to start.
For a separate command, give the full launcher path from `plans[].profile.launcherPath` first (on Windows the `.cmd` file; in PowerShell run it as `& '<path>'`, in cmd as `"<path>"`), then the short name from `nextSteps[].command`, which works by name only once `<RunInfra config>/bin` is on PATH.
The PATH and **Run now** lines in `plans[].notes` and `agent_done.followUp` are written for the shell your tool ran the CLI in; say which shell.
The PATH line lasts one terminal.
Relay `pickHint` and `restart` verbatim, and describe `placement` in words: `fork` is a separate command, `additive` is next to your provider, `slot` replaces the agent's provider.
Notes are for the human: never run `Run now`, the start command, a PATH or shell-profile line, or a note command that sends a model request.
For Goose and Zed, point the human to the private key copy in the plan, `<RunInfra config>/connect/keys/goose.json` or `zed.json`.
In their own terminal or editor, outside this conversation, they copy its `apiKey` value into `RUNINFRA_API_KEY` in the environment that starts the app; Zed also allows its RunInfra provider settings.
They must fully restart the app. Never open the file or print the key yourself.
For other environment-based connections, relay the plan's remaining environment step without handling its key.
Do not claim the current running session has changed before its restart or model-selection instructions are satisfied.

### 8. Verify without another paid request

```bash theme={"dark"}
runinfra doctor --json
```

Find the row whose `agent` is your connection name from `plans[].agent`, for example `claude-run`, not `claude`.
`ok: true` with `link: "config"` means the written files match the saved connection; it does not prove the agent restarted.
Your native agent's row and other agents' rows say `No Connect configuration is recorded for this agent.`; ignore them.
Rows with `agent: null` are host checks: `ok` and `skip` pass, `warn` and `unknown` are advisories.
After a fresh sign-in, `host:sign-in` is `unknown` because Doctor does not contact the server to validate sign-in, and on Windows the `storage:*` rows are `warn` because a read-only check cannot verify file privacy.
Do not sign in again, change permissions, reconnect, or run a command from a hint because of these rows.
If your key lives in the environment (Goose, Zed, Mistral Vibe, Oh My Pi), your row shows `ok: false` with `link: "key"` until `RUNINFRA_API_KEY` holds the key in the shell Doctor runs in; report that as the human's remaining step.
Otherwise report your row when `ok` is `false`, quoting its `message` and `hint`.
This command diagnoses without changing the connection or sending paid inference.
Do not add `--verify`; that sends paid requests and needs separate consent.

### 9. Undo when asked

```bash theme={"dark"}
runinfra disconnect <id> --json
```

For a separate profile, use the connection name returned in its plan, such as `claude-run`, in place of `<id>`.
Show the restore plan and key revocations.
Disconnect revocations name the key as `keyId`; the sessions warning is on stderr.
Do not disconnect the profile you are running in. Ask the human to return to their usual agent first.
If the app must close before restoration, hand the reviewed command to the human as in step 6.
Warn that deleting a profile also deletes its sessions and history.
After explicit approval, repeat with `--yes`:

```bash theme={"dark"}
runinfra disconnect <id> --json --yes
```

Do not add `--force` or `--keep-key` unless the human has reviewed their effects.
If files changed since setup, preserve those edits and follow [CLI troubleshooting](/docs/tools-sdks/connect-troubleshooting).

## Exit codes

| Exit | Meaning |
| - | - |
| `0` | Success. For no-wait login, inspect `pending` before continuing. |
| `1` | Unexpected internal error. |
| `2` | Bad usage, unsupported runtime, or local precheck. |
| `3` | Not signed in, denied, expired, revoked, or `auth_pending`. |
| `4` | Entitlement or plan refused, or the requested agent, key, or resource was not found. |
| `5` | Network, server, readiness, or requested measurement unavailable. |
| `6` | Integrity or configuration verification failure. |
| `7` | Local preparation failed or storage is unavailable. |
| `8` | Consent required before the command may continue. |
| `9` | Consent was refused. |
| `130` | Interrupted. |

## Error codes and recovery

Read the returned `message`, `hint`, `reason`, and `recovery` where present.
For whoami, the error code is nested in `error`; login failures put `code` at the top level.

| Code | Recovery |
| - | - |
| `auth_pending` | Repeat the bounded device wait while the code remains valid. |
| `not_authenticated`, `auth_expired`, `auth_timeout` | Start device sign-in, relay the new code, and wait for the human's approval. |
| `auth_denied` | Stop and relay the message and hint. If the human denied the request, start a new one only when they ask. Permission, billing-hold and shared-key refusals need the workspace owner. If any sign-in output mentions a shared key, a workspace API key or `Browser sign-in is unavailable`, stop: tell the human automated sign-in is unavailable and that they must not paste a key into this conversation. Never pipe a key into `runinfra`. |
| `auth_failed` | Read the hint. Start a fresh device request if it requires a new sign-in. Never ask for a key. |
| `consent_required` | Show the full plan, obtain yes, then repeat with `--yes`. From a `--yes` command, for example `This key's payer changed since review. Prepare a new review.`, run the review again without `--yes` and get a new yes. |
| `consent_refused` | Stop. Do not retry with `--yes`. |
| `usage` | Fix the command using the CLI help. `This agent is not in the connection registry.` means the ID is wrong; use the exact CLI ID from step 3, for example `grok`, not `grok-build`. For a new connection next to the provider, omit `--name`. |
| `unsupported_runtime` | Use a supported runtime or installation channel. Ask before installation changes. |
| `config_modified` with `refused[]`, exit `6` | A review refusal; see step 5. |
| `agent_not_installed` | Only from `--detected` and `launch`. Check your own ID and installation. Do not connect a different detected agent. |
| `not_found` | Read which resource is missing. If the server does not provide coding plan information, report that limitation; do not reinstall or switch agents. For a missing key, check the named connection. |
| `not_entitled` | Read the funding or coverage reason. Let the human resolve billing, workspace access, or model coverage before retrying. |
| `network`, `server_error`, `rate_limited` | Honor a returned retry delay, including sign-in's `error.retryAfter` in seconds. Retry reads after the delay. After a failed `--yes`, prepare a fresh review without `--yes`, show it and wait for a new yes. |
| `config_modified` | Without `refused[]`: if the pending request changed or was cleared, rerun sign-in. If it could not be read safely, review `runinfra logout --local --json`; after explicit consent, repeat with `--yes`, then start device sign-in again. Local logout removes saved sign-in without revoking server access. The old terminal key stays active until it expires or is revoked under **Terminal sessions** in [Settings > API keys](https://runinfra.ai/settings/api-keys). For connection files, preserve edits and inspect recovery; never force restoration automatically. |
| `probe_failed` | Comes from `doctor --verify` or `keys rotate`, not connect. |
| `changes.verificationFailed: true` | Settings saved, paid check failed; see step 6. |
| `storage_unwritable`, `disk_space` | Ask the human to fix access to the named path. For a Codex sandbox failure, ask to run the command outside it. Never move the configuration directory or weaken file privacy. |
| `checksum_mismatch`, `artifact_changed`, `range_mismatch` | Stop the update or transfer. Do not bypass integrity checks. |
| `artifact_not_ready`, `ranges_unsupported` | Read the availability reason. Do not treat an unavailable artifact or transfer capability as a completed update. |
| `interrupted`, `batch_incomplete` | Report recorded completed changes. After a failed or interrupted `--yes`, prepare a fresh review without `--yes`, show it and wait for a new yes. |
| `unexpected` | Stop and report the sanitized error. Do not retry a mutation without checking what completed. |

## Troubleshooting

If approval is still pending, keep the same CLI configuration directory and repeat the bounded wait.
If the agent cannot be detected, check its own row's `reason` rather than assuming it is uninstalled.
If the current session still uses your earlier provider, follow the exact model-picker and restart instructions in `nextSteps`.
For billing, configuration conflicts, or a failed paid check, use [CLI troubleshooting](/docs/tools-sdks/connect-troubleshooting).
See [JSON output](/docs/tools-sdks/connect-json-output) for field details and [CLI commands](/docs/tools-sdks/connect) for other operations.

## Short JSON examples

These are excerpts from CLI 0.4.1 against a test service; IDs, paths and times are placeholders.
Read the [complete JSON examples](/docs/tools-sdks/connect-json-output) for both payers, Doctor after connecting, and removal of a real connection.
The test service issues one-day access and 10-minute codes; production terminal access lasts 90 days and codes last 15 minutes.

Pending sign-in, exit `0`; relay the code and wait for the human:

```json theme={"dark"}
{"pending":true,"userCode":"ABCD-EFGH","verificationUri":"https://runinfra.ai/cli/authorize","expiresAt":"2026-09-29T10:33:55.439Z","ok":true,"exitCode":0}
```

Setup review, exit `8`. This excerpt omits the file list and notes; show every returned field in the actual review:

```json theme={"dark"}
{"code":"consent_required","plan":[{"agent":"claude-run","paidRequests":1,"keysCreated":1,"keysRevoked":0}],"ok":false,"exitCode":8}
```

Applied result, exit `0`. This excerpt omits the events and next steps; read them before claiming success:

```json theme={"dark"}
{"changes":{"verificationFailed":false},"ok":true,"exitCode":0}
```

## Terminal app

The terminal app is for people at a terminal.
Coding agents must never run bare `runinfra` or `runinfra launch` because those commands can open an interactive application or start a child agent session.
Use the numbered JSON command procedure above.
