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

# The envlink skill

> The SKILL.md that teaches a coding agent to use envlink: what it says, where it's installed, and how to change it.

The envlink skill is a single `SKILL.md` in the [Agent Skills](https://agentskills.io) format: front matter with a name and a description, then instructions. Agents load it when a task matches its description: building or testing remotely, needing a database on `localhost`, sharing a build output.

It's built into envctl, so it always matches the CLI you have:

```bash theme={null}
envctl skills show       # print it
envctl skills install    # install it for your agents
```

## Change it

Edit the installed copy, for example `.claude/skills/envlink/SKILL.md`, to add your team's conventions, such as which labels to use or which make targets to run. Running `envctl skills install` again replaces your edits with the built-in version, so keep your changes in a second skill if you want them to last, or in your agent's project instructions (`CLAUDE.md`, `AGENTS.md`).

## The full text

````markdown SKILL.md theme={null}
---
name: envlink
description: Lease remote build environments with envctl (a Linux build box, a Postgres, a hosted sandbox), sync this folder to them, run builds and tests there, and get results back as local files. Use when asked to build, test or run something remotely, to get a database on localhost, to share a build output, or to keep heavy work off this machine.
---

# envlink

envlink leases isolated environments from a pool of warm gVisor nodes and wires them to this machine over a private tailnet. This machine is the **sandbox**: folders you share sync up to the environment, commands run there with `envctl exec`, and whatever the environment writes to `/work/out` comes back under `.remote/<environment>/out/`. Services such as Postgres appear on this machine's `localhost`.

## Before you start

1. Check envctl is installed and logged in: `envctl templates`. If it says "not logged in", ask the user for a CLI token from the console (Settings → CLI tokens) and run `envctl login --api <api-url> --token <token>`. Never invent or print a token.
2. Make this machine the sandbox, once per working folder: `envctl sandbox up`. Shared paths are relative to the folder where you run it. `envctl sandbox status` shows whether it's running.

## The loop

```bash
# 1. Lease a build box and share this folder to its /work
envctl env create linux-build --share src=. --label task=<short-id>

# 2. Run commands there; output streams back and the exit code is the remote one
envctl exec <name> -- sh -c 'cd /work && make test'

# 3. Results the command writes to /work/out are here when exec returns
ls .remote/<name>/out/

# 4. Release it when you're done
envctl env delete <name>
```

`env create` prints the environment's name (like `linux-build-3f2a`) and waits until it's ready, usually 3–4 seconds. `envctl env list --label task=<short-id> --json` finds it again later. Always delete what you leased once the task is finished; idle environments stop on their own after an hour, but don't rely on it.

## Templates

`envctl templates` lists them. The common ones:
- `linux-build`: Go, C and C++, Python, Node and Bazel in `/work`. Use it for builds and tests.
- `postgres`: a Postgres on this machine's `127.0.0.1:5432` (the next free port if that's taken). Ready means it accepts connections.
- `agent-sandbox`: a hosted Linux sandbox for running untrusted code.

## What gets synced

- `.gitignore` files are honoured, and dependency and cache folders (`node_modules/`, `.venv/`, `__pycache__/`, `.gradle/`, `.next/`, …) stay home. Install dependencies in the environment instead of sending them.
- `--include 'dist/**'` brings back something the ignore rules leave out.
- Secret files (`.env*`, private keys, `.netrc`, `secrets/`, `.ssh/`) never leave, even with `--include`. If the build truly needs one, ask the user first, then send it explicitly with `--file <source>=<destination>`, for example `--file ~/.npmrc=.npmrc`. It arrives readable only in the environment and is never stored or snapshotted.
- `envctl sync` syncs now and waits for the environment's ack; `envctl exec` already syncs before it runs.

## Useful flags

| Flag | Use it to |
|---|---|
| `--label k=v` | tag what you lease, so you can find and delete it later |
| `--idle 30m`, `--hard 2h` | shorten how long an unused or long-running lease lives |
| `--snapshot main` | save the synced files when the environment ends, so the next one starts warm |
| `--restore main` | start from the newest snapshot saved under `main`; the first sync then sends only what changed |
| `--project <name>` | choose whose encryption key seals the files (default: the git remote and path) |
| `envctl exec --timeout 300` | stop a command after 300 seconds (exit code 124) |
| `envctl exec --dir /work/sub` | run from another directory |

## Bazel

The `linux-build` box has Bazel and a remote cache on `localhost:9092` that is already configured. A project's next build box reuses that cache, so a repeated build finishes from cache hits. Just run `bazel build //...` in `/work`.

## Sharing a result

```bash
envctl artifact put .remote/<name>/out/app.tar.gz --link 24h
```

prints a signed download link that works without an account until it expires. `envctl artifact get <id>` downloads and checks the sha256.

## Rules

- Prefer running builds and tests remotely when the user asked for envlink; don't install toolchains locally.
- Report the exit code and the relevant output; on failure, read the error before retrying.
- Never print tokens, never send secret files unless the user asked, and delete every environment you created when you finish.
````


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.