# Setting Up Remote Agent Environment

Set up a remote machine for development or a coding agent. You will need SSH
access, Git access to the repository, and the runtime versions specified by the
project.

The examples use `dev-box` as the SSH alias and `alice` as the DreamLake account.
Replace both with your own values.

## Connect to the machine

Run on your local machine:

```shell
ssh dev-box
```

For provisioning and network/key prerequisites, see [Resource setup](/lakeshore/providers/resource-setup.md).

## Prepare a checkout

Run on the remote machine. This example creates a separate DreamLake CLI checkout
and checks out a specific commit. Replace the revision before running it.

```shell
bash <<'SH'
set -eu
TASK_REVISION='REPLACE_WITH_FULL_COMMIT_SHA'
case "$TASK_REVISION" in
  REPLACE_*) printf '%s\n' 'Set TASK_REVISION first'; exit 1 ;;
esac

mkdir -p "$HOME/workspaces"
TASK_DIR=$(mktemp -d "$HOME/workspaces/dreamlake-cli-task.XXXXXX")
git clone https://github.com/dreamlake-ai/dreamlake-cli.git "$TASK_DIR"
cd "$TASK_DIR"
git switch --detach "$TASK_REVISION"
git switch -c work/remote-dev
printf 'Checkout: %s\n' "$TASK_DIR"
git rev-parse HEAD
SH
```

Use the printed checkout path as the working directory for your editor or agent.
Each concurrent task should have its own checkout and branch.

Install the Node and pnpm versions specified by the checkout, then run from that
directory:

```shell
bash <<'SH'
set -eu
node --version
pnpm --version
pnpm install --frozen-lockfile
pnpm run build
pnpm test
SH
```

## Configure access

Set up the services your project uses on the remote machine.

| Service | Local configuration | Remote setup |
| --- | --- | --- |
| DreamLake | `~/.dreamlake/` | Run `dreamlake login`. |
| Application or integration tests | `.env`, `.env.test` | Create from the project's example file and supply the required values. |
| SSH | `~/.ssh/config`, selected keys | Add the required host entries and keys. |
| AWS | `~/.aws/config`, credentials or SSO session | Configure the required profile and log in. |
| Google Cloud | gcloud configuration and application credentials | Authenticate the remote account or provision its service identity. |
| Kubernetes | kubeconfig | Install the required cluster context. |
| GitHub, npm, Docker | CLI login and registry configuration | Log in on the remote machine. |

Desktop keychain credentials and hardware-backed keys require remote login or a
separate remote credential. For existing deployments, retain the encryption keys
needed to read stored data and use the authoritative Terraform state/backend.

## Upload configuration files to the vault

Use a CLI version with vault support and a vault-enabled server. See
[#241](https://github.com/dreamlake-ai/dreamlake-workspace/issues/241) for release
and deployment status.

Run on the local machine:

```shell
dreamlake login
dreamlake vault add --help

# Application configuration.
dreamlake vault add -n alice/remote-agent/app-env \
  --stdin --file-name .env < ./service/.env

# A selected SSH private key.
dreamlake vault add -n alice/remote-agent/ssh-key \
  --stdin --file-name id_ed25519 < "$HOME/.ssh/remote_agent_ed25519"

# A selected cluster configuration.
dreamlake vault add -n alice/remote-agent/kubeconfig \
  --stdin --file-name config < ./selected-cluster.kubeconfig

dreamlake vault list -p alice/remote-agent
dreamlake vault show -n alice/remote-agent/app-env
```

Run only the uploads you need. `--stdin` preserves UTF-8 text and trailing
newlines; the JSON-encoded value is limited to 64 KiB. `--file-name` records a
suggested filename. To replace an existing entry, inspect its revision with
`show` and pass that revision with `--if-match`.

`dreamlake upload` is for episode assets. Use `dreamlake vault add` for secrets.

<span id="select-ssh-entries-to-sync" />

## Select SSH entries to import

Selected SSH import is available in the released clients. See the [credential guide](/lakeshore/hosts/credentials.md) for supported versions, CLI/Python usage and current limitations.

Run in an authenticated interactive terminal on your local machine:

```shell
dreamlake vault import --ssh -p alice/remote-agent
```

The checklist starts with no entries selected. Profiles and private keys are
separate items:

```text
Select SSH entries to upload

[ ] dev-box profile       dev@dev.example.com
[ ] dev-box private key   ~/.ssh/dev_box
[ ] bastion profile       dev@jump.example.com
[ ] bastion private key   ~/.ssh/bastion

Space: select    Enter: review selected    Esc: cancel
```

Select the entries you want, review their vault destinations, and upload the
selection. Only checked entries are uploaded. An empty selection or cancellation
before upload writes nothing. Private keys and jump-host entries require their
own selection.

To inspect discovered items without reading private keys or contacting the vault:

```shell
dreamlake vault import --ssh -p alice/remote-agent --dry-run --json
```

See [SSH import](/lakeshore/hosts/credentials.md#ssh-sync-select-entries-before-uploading)
for the selection and retry behavior.

## Restore a file remotely

Log in on the remote machine:

```shell
dreamlake login
```

From your application checkout, restore the saved environment file to
`service/.env`. The `service` directory must already exist. This example creates
a mode-0600 file and fails if the destination exists or retrieval fails.

```shell
python3 - <<'PYTHON'
import json
import os
from pathlib import Path
import subprocess

destination = Path("service/.env")
if not destination.parent.is_dir():
    raise SystemExit("Create the service checkout first")
result = subprocess.run(
    ["dreamlake", "vault", "get", "-n", "alice/remote-agent/app-env", "--to-json"],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
)
if result.returncode:
    raise SystemExit("Vault retrieval failed")
value = json.loads(result.stdout)
if not isinstance(value, str):
    raise SystemExit("Expected a text-file entry")
fd = os.open(destination, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
with os.fdopen(fd, "wb") as output:
    output.write(value.encode("utf-8"))
print("Created service/.env")
PYTHON
```

Change the entry name and destination for other files. Use mode `0700` for SSH
and credential directories. For individual environment variables, see
[Environment exports](/lakeshore/hosts/credentials.md#supply-values-to-a-program).

## Run development tools or an agent

Start your editor or coding agent in the remote checkout under the account that
owns the configuration files. Use the project's commands to start the service
and run its checks. Applications that read `.env` files must use the configured
file location; other programs need the variables exported into their process
environment.

The DreamLake CLI development example uses `pnpm run build` and `pnpm test`.
Application integration tests may additionally need the configuration restored
above. Set up remote agent authentication separately if your agent requires it.

## Check the setup

- Confirm the checkout revision with `git rev-parse HEAD`.
- Run the project's build and tests from the remote account.
- Check required configuration files exist and have the intended permissions.
- Verify access to each required API, registry or cluster with a read-only call.
- Verify SSH access with a fresh connection.

Keep secret values out of terminal output and logs. If a check fails, fix its
reported dependency, configuration or authentication error and rerun that check.
