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

# Set up Aether with a coding agent

> Canonical instructions for a coding agent to install and configure Aether for its human

# Set up Aether with a coding agent

## Instructions to the executing agent

You are setting up Aether for your human. Execute the steps below in order from the repository your human wants to use with Aether. Do not use `aether setup`; that command intentionally requires an interactive terminal.

After **every** step, run its verification probe. Do not continue when a probe fails, and **NEVER claim that a step succeeded unless its probe passed**. Diagnose a failure, retry the step once, and rerun the probe. If the same step fails twice, stop and report the command, the error, and the failed probe honestly.

When a step needs a browser, keep the CLI command running, immediately give your human the printed URL, tell them exactly what to do there, and poll or wait until the CLI reports success. Do not ask your human to paste a credential, token, authorization code, secret value, or file contents into the agent conversation.

A URL can be opened on any device with a browser. A **command** is different: it must run on this computer — the machine this session is running on. Whenever you hand your human a command to run themselves: say explicitly that it must run on this computer and name its operating system; if your human may not know how, include how to open the terminal application (macOS: press Cmd+Space, type Terminal, press Enter); and write the command using the absolute path to the `aether` binary whenever it is installed outside `PATH`. A command pasted into the wrong machine's shell fails confusingly — prevent that, don't recover from it.

Secret files have an additional, non-negotiable consent gate: you may list candidate **paths**, but you must never choose or upload a file on your own judgment. Ask your human which exact paths, if any, they approve. Upload only those paths.

## 1. Install the Aether CLI

Run:

```bash theme={"dark"}
curl -fsSL https://app.runaether.dev/install.sh | sh
```

Expected output includes:

```text theme={"dark"}
Downloading Aether for <os>/<arch>...

Aether installed to <install-directory>/aether
```

Verification probe:

```bash theme={"dark"}
aether version
```

The probe passes only if it exits zero and prints `aether version` plus the Go and OS/architecture lines.

If installation fails, report the installer error. Check that `curl`, `tar`, `install`, and the platform checksum tool are available and that the install directory is writable. Retry once; do not substitute an unverified binary or claim success from a downloaded file alone.

If the install directory is outside `PATH` — for example, you set `AETHER_INSTALL_DIR` to a user-writable directory because the default needed sudo — the installer prints the shell-profile line to add. From then on, use the absolute binary path (`<install-directory>/aether`) in every command you run **and every command you hand to your human**. You may offer to append the printed `PATH` line to your human's shell profile, but only with their explicit consent; do not edit shell configuration unasked.

## 2. Authenticate the Aether account

First run the probe. If it already prints `Logged in` or `Authenticated via AETHER_TOKEN environment variable`, this step is complete.

Otherwise, start the browser callback flow in the headless shell:

```bash theme={"dark"}
aether login
```

Expected output includes a URL like:

```text theme={"dark"}
https://app.runaether.dev/login?port=<port>&state=<state>
Waiting for authentication...
```

Immediately give that URL to your human and say: **“Open this URL in a browser, sign in to Aether, and leave this command running until I confirm it completed.”** The CLI blocks while it waits for the localhost callback. Success ends with:

```text theme={"dark"}
Logged in
  Config saved to: <path>
```

Verification probe:

```bash theme={"dark"}
aether auth status
```

The probe passes only when it reports `Logged in` or authentication through `AETHER_TOKEN`. `Not logged in` is a failed probe even though the status command itself exits zero.

If the callback times out or the credential is rejected, run `aether login` again to obtain a fresh URL. Never ask for a token as a workaround. Stop after a second failed login or probe.

## 3. Connect GitHub

Run the verification probe first. If it already prints `GitHub: connected` and at least one installation, do not start a second installation flow.

Otherwise run:

```bash theme={"dark"}
aether github connect
```

Expected output includes the installation URL and then waits:

```text theme={"dark"}
Connect GitHub in your browser.

  Install the Aether GitHub App to grant repository access.
  URL: https://github.com/apps/<app>/installations/new...
  Waiting for connection...
```

Immediately give the printed URL to your human and say: **“Open this URL, install or configure the Aether GitHub App, grant access to the repository we are setting up, and return here. I will keep polling.”** Do not terminate the command while the human is in GitHub. Success prints `GitHub connected`.

Verification probe:

```bash theme={"dark"}
aether github status
```

The probe passes only if the output starts with `GitHub: connected` and lists at least one `Installation`. `GitHub: not connected` and `GitHub: reauthorization required` are failures.

If the repository is not covered by the installation, rerun the connection flow and tell the human to add that repository. Retry once, then stop and report the status output.

## 4. Connect coding-agent providers

At least one of OpenCode, Codex, or Claude Code must pass its status probe before onboarding can complete. Connect each provider that your human already uses locally. Do not treat “not configured” as success, and do not stop at “skip providers” when none is installed or logged in.

### If no provider is installed or logged in

Ask your human which coding agent they already use or want to use, and explain the account each connect flow expects:

* **Claude Code:** a Claude Pro, Max, Team, or Enterprise subscription.
* **Codex:** an eligible ChatGPT plan. Current supported plans include Free, Go, Plus, Pro, Business, Edu, and Enterprise, with different usage limits.
* **OpenCode:** no single subscription is required, but it needs a supported model-provider login or API credential. OpenCode Go is its subscription option; OpenCode Zen is pay-as-you-go.

After they choose, offer to install that agent on this computer. The agent must run the installer; do **not** hand the install command to the human. Before running anything, show the exact command appropriate for this computer's operating system and ask for explicit consent. Use the lowest-dependency official command:

* Claude Code on macOS, Linux, or WSL: `curl -fsSL https://claude.ai/install.sh | bash`
* Claude Code in Windows PowerShell: `irm https://claude.ai/install.ps1 | iex`
* Codex on macOS or Linux: `curl -fsSL https://chatgpt.com/codex/install.sh | sh`
* Codex on Windows: `powershell -ExecutionPolicy ByPass -c "irm https://chatgpt.com/codex/install.ps1 | iex"`
* OpenCode on macOS, Linux, or WSL: `curl -fsSL https://opencode.ai/install | bash`
* OpenCode on native Windows: use `choco install opencode` if Chocolatey is already installed, or `scoop install opencode` if Scoop is already installed. Otherwise stop and explain that OpenCode's official guidance recommends WSL; do not install another package manager without separate consent.

Do not infer consent from the agent choice. Run only the exact command the human approved, then immediately verify it with the matching probe:

```bash theme={"dark"}
claude --version
codex --version
opencode --version
```

Run only the probe for the installed agent. It passes only if it exits zero and prints a version. If installation or the probe fails, diagnose and retry once under the existing probe discipline; never fabricate an installation or login. After the probe passes, continue with that agent's normal connect leg below. The human only consents to installation and completes browser sign-in; the driving agent runs the installer, login, connect, and verification commands.

### OpenCode — fully non-interactive

If `${XDG_DATA_HOME:-~/.local/share}/opencode/auth.json` exists, run:

```bash theme={"dark"}
aether opencode connect
```

This reads and uploads that local auth file without a prompt. Expected output:

```text theme={"dark"}
OpenCode connected (uploaded <bytes> bytes from <path>/opencode/auth.json).
```

Verification probe:

```bash theme={"dark"}
aether opencode status
```

The probe passes only if it prints `OpenCode: configured`. If the local file is absent, ask which supported model provider the human uses, then run `opencode auth login --provider <human-chosen-provider>` from the agent shell. Relay a browser sign-in URL immediately and keep the command running while the human approves it. Do not invent the provider, request a secret, or ask the human to paste an API key. If the chosen method requires manual secret entry instead of browser sign-in, stop and report that it cannot be completed through this agent-guided flow. After browser login, verify that `opencode auth list` names the chosen provider, then retry the Aether connection once. Treat an invalid auth file as a failure; do not fabricate or modify its contents.

### Codex — device flow requiring human confirmation

Run:

```bash theme={"dark"}
aether codex connect
```

Expected output:

```text theme={"dark"}
Open this URL and enter the code:
  <verification-url>
  Code: <device-code>
Waiting for Codex authorization...
```

Immediately give your human the verification URL and code and say: **“Open this URL, enter this code, and approve Codex access. I will keep the command running.”** The CLI polls until authorization succeeds. Expected success is `Codex subscription auth connected.`

Verification probe:

```bash theme={"dark"}
aether codex status
```

The probe passes only if it prints `Codex: configured`. If the device code expires, start the command once more and provide the new URL and code. Stop after the second failed flow or probe.

### Claude Code — headless browser flow (aether ≥ 0.2.5)

Headless support requires **aether 0.2.5 or newer**. Because this guide is served live before every workspace has the latest released binary, attempt the command headlessly first, but treat `claude setup-token did not display a sign-in link within 30s` as the tell that the installed aether is older and still has the non-TTY rendering bug.

Run from the agent shell:

```bash theme={"dark"}
aether claude-code connect
```

Relay the printed sign-in URL to your human immediately and say: **“Open this URL and approve Claude access. I will keep the command running.”** Keep the command running while the browser flow completes. Expected success is:

```text theme={"dark"}
Claude Code setup token connected.
```

Only if the headless command errors — including the older-binary 30-second failure above — fall back to a human terminal. Use the absolute aether path established in step 1 (or resolve it with `command -v aether` when aether is on `PATH`) in the handoff. Name this computer's detected operating system and tell your human exactly:

* On macOS: **“On this computer (macOS), press Cmd+Space, type Terminal, press Enter. In Terminal, run `<absolute-path-to-aether> claude-code connect` and complete the Claude browser flow. Do not paste the token or code here. Tell me when the command succeeds.”**
* On another operating system: **“On this computer (`<detected-operating-system>`), open its terminal application. Run `<absolute-path-to-aether> claude-code connect` and complete the Claude browser flow. Do not paste the token or code here. Tell me when the command succeeds.”**

Replace the placeholders with the detected operating system and actual absolute binary path before sending the handoff. Then rerun only the probe:

```bash theme={"dark"}
aether claude-code status
```

The probe passes only if it prints `Claude Code: configured`. If the human-run command or the follow-up probe still fails after one retry, stop and report the failure.

Finally, rerun the status probes for every provider attempted. Proceed only when at least one reports `configured`.

## 5. Create or select the project for this repository

An inherited `AETHER_PROJECT` can silently override the stored default. From this step through first-task creation, prefix every project-scoped Aether command with `AETHER_PROJECT=` exactly as shown. This clears only that per-process override; do not unset or change any credential environment variable.

Read the current repository's GitHub remote:

```bash theme={"dark"}
git remote get-url origin
```

Normalize the HTTPS or SSH GitHub URL to its exact `owner/repository` name. First inspect projects using machine-readable output:

```bash theme={"dark"}
AETHER_PROJECT= aether project list --json
```

If an existing project has a `repo_url` for this same repository, select it:

```bash theme={"dark"}
AETHER_PROJECT= aether project select <project-id>
```

Otherwise inspect the accessible GitHub repositories:

```bash theme={"dark"}
AETHER_PROJECT= aether github repos --json
```

The output contains `full_name` and `installation_id`. Find the entry whose `full_name` exactly equals the current remote. Do not guess an installation ID. Then create, select, and link a project. Use the repository name as the project name unless your human already specified another name:

```bash theme={"dark"}
AETHER_PROJECT= aether project create --name "<repository-name>" --json
AETHER_PROJECT= aether project select <project-id-from-create-output>
AETHER_PROJECT= aether github import --repo "<owner/repository>" --installation-id <matching-installation-id>
```

Expected output includes:

```text theme={"dark"}
Default project set to: <name> (<short-id>)
Linked repo: <owner/repository> (<default-branch>)
Clone URL:   <clone-url>
```

Verification probes:

```bash theme={"dark"}
AETHER_PROJECT= aether project get <project-id>
AETHER_PROJECT= aether github link
AETHER_PROJECT= aether config get default_project
```

The probes pass only when the project exists, `aether github link` names the exact current repository, and `aether config get default_project` prints that project's full ID. All of these commands work without a TTY when the IDs and flags above are supplied.

If the repository is absent from `aether github repos --json`, return to the GitHub step and ask the human to grant it access. If create, select, or import fails twice, stop; do not create extra projects to hide the error.

## 6. Claim the devbox prewarm slot (best-effort)

Prewarming builds the project's devbox while the remaining steps run, so the first task starts warm. This step is best-effort by design: no outcome here may stop the setup.

First inspect the current slots:

```bash theme={"dark"}
AETHER_PROJECT= aether warm-slot list --json
```

* If a slot already lists this project's ID, the claim exists; record "prewarm: already claimed" and continue to the next step.
* If a slot has no project assigned, claim it:

```bash theme={"dark"}
AETHER_PROJECT= aether warm-slot assign --project <project-id>
```

* If every slot is held by another project, record "prewarm: unavailable — the first task will cold-start" and continue.

If the assign command reports a missing required flag on your CLI version (for example `--size`), inspect `aether warm-slot assign --help` and rerun once with the smallest documented value (for example `--size medium`).

Verification probe:

```bash theme={"dark"}
AETHER_PROJECT= aether warm-slot list --json
```

The probe passes when a slot lists this project's ID. If the assign command fails for any reason, do not retry more than once and do not stop: record "prewarm: failed — the first task will cold-start" with the exact error and continue. Prewarm never blocks onboarding.

## 7. Install the aether-teleport skill

The `/aether-teleport` skill lets a local coding agent hand its session off to Aether later. Install it when Claude Code or Codex is present in this environment (a `claude` or `codex` executable on `PATH`, or a `~/.claude` or `~/.codex` directory):

```bash theme={"dark"}
aether skill install aether-teleport
```

The installer detects local agents and writes into their skill directories. Expected output names each installed directory. If it reports that no supported agent was detected, record "teleport skill: skipped (no local agent detected)" and continue; do not force a `--dir` the human did not ask for.

Verification probe — check the directories the installer reported, for example:

```bash theme={"dark"}
test -f ~/.claude/skills/aether-teleport/SKILL.md && echo claude-ok
test -f ~/.agents/skills/aether-teleport/SKILL.md && echo codex-ok
```

The probe passes when every directory the installer reported contains `SKILL.md`. The installer is safe to rerun; retry once on failure, then record the failure and continue — this step never blocks onboarding.

## 8. Ask for consent before uploading secret files

List gitignored file paths without reading or printing their contents. Exclude dependency and build-output directories so the list stays reviewable:

```bash theme={"dark"}
git ls-files --others --ignored --exclude-standard -- . \
  ':(exclude,glob)**/.git/**' \
  ':(exclude,glob)**/node_modules/**' \
  ':(exclude,glob)**/dist/**' \
  ':(exclude,glob)**/build/**' \
  ':(exclude,glob)**/.next/**' \
  ':(exclude,glob)**/__pycache__/**' \
  ':(exclude,glob)**/.venv/**' \
  ':(exclude,glob)**/venv/**' \
  ':(exclude,glob)**/.turbo/**' \
  ':(exclude,glob)**/.cache/**'
```

Show the candidate **paths only** to your human and ask: **“Which of these exact files, if any, do you approve uploading to the default Aether project?”** Wait for an explicit answer. An empty selection is valid.

For each and only each approved path, run one command from the repository root:

```bash theme={"dark"}
AETHER_PROJECT= aether secret upload <approved-path>
```

Do not use `aether secret bulk-upload` in this guide. Expected output for each approved file:

```text theme={"dark"}
Uploaded secret file <approved-path>.
```

Verification probe:

```bash theme={"dark"}
AETHER_PROJECT= aether secret list --json
```

The probe passes when every approved path appears exactly once. If the human approved no files, the probe passes when it exits zero; record that this run uploaded zero files. Never use `aether secret get` as a probe because it prints decrypted contents.

If an approved file is missing, unreadable, too large, or rejected, report that path without printing its contents and retry its individual upload once. Do not replace it with another candidate on your own.

## 9. Complete onboarding

Run:

```bash theme={"dark"}
aether onboarding complete
```

Expected output is one of these idempotent successes:

```text theme={"dark"}
Onboarding completed.
```

```text theme={"dark"}
Onboarding already completed.
```

Verification probe: run the same idempotent command again.

```bash theme={"dark"}
aether onboarding complete
```

The probe passes only if it exits zero and prints `Onboarding already completed.` If the server returns `403`, report its requirements-missing message verbatim, return to the named missing GitHub or provider step, and retry completion once after that probe passes. Never hide or paraphrase the server's missing-requirements error.

## 10. Launch the first task

Check for the repository's Aether environment file without modifying it:

```bash theme={"dark"}
if test -f .aether/environment.json; then echo present; else echo absent; fi
```

If the file is absent, use the CLI's canonical embedded environment-bootstrap prompt. Do not reproduce, summarize, or inline that prompt:

```bash theme={"dark"}
AETHER_PROJECT= aether run --bootstrap-environment --json
```

If the file exists, start with a friendly exploration task:

```bash theme={"dark"}
AETHER_PROJECT= aether run "explore this repository and suggest an improvement" --json
```

Expected stdout is a JSON task object containing a nonempty `id`. (`Creating task... done` may appear separately on stderr.) Extract the full task ID from the JSON and construct:

```text theme={"dark"}
https://app.runaether.dev/agents/<full-task-id>
```

Verification probe:

```bash theme={"dark"}
aether task get <full-task-id> --json
```

The probe passes only when it exits zero and returns that same task ID. If task creation or lookup fails, retry the same branch once; do not switch away from the embedded bootstrap prompt to make the task easier to create.

Give the verified web URL to your human and say: **“Aether is set up. Your first task is running here: `<task-url>`.”**

## Final report to your human

Report this checklist using only facts proven by the probes:

```text theme={"dark"}
- Account: connected
- GitHub: connected (<installation account(s)>)
- Coding provider(s): <configured provider names>
- Default project: <project name> (<full project id>), linked to <owner/repository>
- Devbox prewarm: <claimed | already claimed | unavailable or failed (first task cold-starts)>
- Teleport skill: <installed into <dirs> | skipped (no local agent detected)>
- Secret files uploaded by this run: <count>
- Onboarding: completed
- First task: <task web URL>
```

If any item is not proven, do not print a completed checklist. Stop at the failed step and report it honestly.
