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

# Configuration

> Environment variables, the files Tesser writes, the ports it uses, and the timers

There is no configuration file to edit. `tesser login` writes the one
credential the CLI needs, and everything else is controlled by command-line
flags or environment variables.

## Environment variables

| Variable                | What it does                                                                                                                     |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `TESSER_TOKEN`          | Use this API token instead of the saved credential. Intended for CI; use it together with `TESSER_ORG`.                          |
| `TESSER_ORG`            | Run in this org instead of the saved default.                                                                                    |
| `TESSER_CONFIG_DIR`     | The directory that holds credentials and the default org. Defaults to `~/.config/tesser`, or `$XDG_CONFIG_HOME/tesser` if set.   |
| `TESSER_STATE_DIR`      | The directory that holds per-box keys and daemon state. Defaults to `~/.local/state/tesser`, or `$XDG_STATE_HOME/tesser` if set. |
| `TESSER_CONTROL_URL`    | A different control plane. The production URL is built into the release binary, so this is not normally needed.                  |
| `TESSER_INSTALL`        | Used by the installer only: the install root. Defaults to `~/.tesser`.                                                           |
| `TESSER_VERSION`        | Used by the installer only: the release to install, equivalent to `sh -s -- v0.2.5`.                                             |
| `TESSER_NO_MODIFY_PATH` | Used by the installer only: set to `1` to leave your shell rc files unchanged.                                                   |

## Files on the laptop

| Path                                    | Contents                                                                                           |
| --------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `~/.tesser/bin/tesser`                  | The binary.                                                                                        |
| `~/.config/tesser/credentials.json`     | One API token per control plane and org, with mode 0600.                                           |
| `~/.config/tesser/config.json`          | The default org.                                                                                   |
| `~/.local/state/tesser/boxes/<box_id>/` | That box's SSH key pair and known host entry. The private key never leaves this machine.           |
| `~/.local/state/tesser/`                | Which box belongs to which worktree, the switcher's targets and selection, and the daemon's ports. |
| `~/.claude/skills/tesser/SKILL.md`      | The agent skill, if you installed it.                                                              |

Nothing is installed system-wide, and nothing requires root.

## Ports on the laptop

| Port             | Used for                                                                                                             |
| ---------------- | -------------------------------------------------------------------------------------------------------------------- |
| 3000             | The proxy: the selected box, and the `<box_id>.localhost:3000` addresses. `tesser daemon --port` moves it.           |
| 4100             | The switcher widget. `--widget-port` moves it.                                                                       |
| 42000 to 42999   | SSH tunnels to boxes, one per box, chosen automatically.                                                             |
| declared ports   | Every port a service manifest declares is bound once on the laptop and shared by all boxes, told apart by host name. |
| dependency ports | The selected box's `[deps]` ports, so browser code reaches what the box reaches.                                     |

The daemon answers requests from your own machine and from Tailscale peers.
It refuses the rest of the LAN unless it is started with `--allow-lan`.

## Timers

| Event                         | When                        |
| ----------------------------- | --------------------------- |
| Workbench goes to sleep       | after 10 minutes idle       |
| Instance box goes to sleep    | after 2 hours idle          |
| Sleeping box is removed       | after 16 hours asleep       |
| Unclaimed pool box is removed | after 1 hour                |
| Health check gives up         | after 90 seconds by default |
| Browser sign-in expires       | after 10 minutes            |

## The box

Each box is an m7a.large (2 vCPU, 8 GB of memory) with a 40 GB gp3 disk,
running Ubuntu 24.04 with Node 22, rsync, and Docker installed. Your worktree
is at `~/workspace` and the dev server's output is written to
`~/.tesser/dev.log`. Commands run as the `ubuntu` user, which has passwordless
sudo and is in the docker group.
