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

# Configuration

> Environment variables, state files, cache, and logs.

## Environment variables

| Variable                   | Purpose                                                 | Default                   |
| -------------------------- | ------------------------------------------------------- | ------------------------- |
| `XYSQ_API_KEY`             | API key (beats keychain at runtime; never written back) | none                      |
| `XYSQ_API_BASE`            | API root URL (override for staging / local backend)     | `https://api.xysq.ai`     |
| `XYSQ_MCP_URL`             | MCP server URL inlined into agent configs               | `https://api.xysq.ai/mcp` |
| `XYSQ_HOME`                | Override the CLI's state/cache/logs directory           | `~/.xysq`                 |
| `XYSQ_HTTP_TIMEOUT_MS`     | HTTP request timeout in milliseconds                    | 10000                     |
| `XYSQ_DOWNLOAD_TIMEOUT_MS` | Skill zip download timeout                              | 60000                     |
| `NO_COLOR`                 | Disable ANSI colors (same as `--no-color`)              | unset                     |

## State and cache

Everything the CLI persists locally lives under `~/.xysq/` (or `$XYSQ_HOME`):

```
~/.xysq/
├── state.json            # what's wired where, skill version, last validation
├── skills-cache/v8/      # downloaded skill files, keyed by version
├── backups/              # pre-modification copies of every config file we touched
└── logs/cli-YYYY-MM-DD.log
```

### state.json

Non-secret metadata. Records which agents the CLI has wired, what skill version is installed, and the last validated user identity. The API key is **never** stored in `state.json` — it lives in your OS keychain.

State is treated as observation, not authority: every command re-reads each agent's actual config file before deciding what to do. If you manually edit an MCP config and run `xysq doctor`, it'll detect the change.

### Skill cache

Downloaded skill files are cached under `~/.xysq/skills-cache/v<version>/`. Re-running `xysq install` with no version bump on the backend hits the cache and skips the download.

To force a re-fetch, delete the cache directory:

```bash theme={"dark"}
rm -rf ~/.xysq/skills-cache
xysq update-skills
```

### Backups

The first time the CLI modifies any agent config, it copies the original to `~/.xysq/backups/<agent>-<timestamp>.bak`. The last 5 backups per agent are retained.

To restore from a backup, copy the file back manually:

```bash theme={"dark"}
cp ~/.xysq/backups/codex-20260516T142200Z.bak ~/.codex/config.toml
```

### Logs

The CLI writes one log file per day under `~/.xysq/logs/cli-YYYY-MM-DD.log`. Logs are rolled daily and retained for 14 days.

All log lines redact API keys at write time (`Bearer xysq_••••`), so the file on disk is safe to share when filing a bug report.

## Where the API key is stored

| Platform                           | Location                                                |
| ---------------------------------- | ------------------------------------------------------- |
| macOS                              | Keychain Access — service `xysq-cli`, account `default` |
| Windows                            | Credential Manager — generic credential `xysq-cli`      |
| Linux                              | libsecret (Secret Service API) — service `xysq-cli`     |
| Fallback (Linux without libsecret) | `~/.xysq/credentials` with `chmod 600`                  |

The key is never written to `state.json`, never echoed back, and never logged in plaintext.

To rotate:

```bash theme={"dark"}
xysq login --replace                   # paste new key, validates, replaces
xysq install                            # re-write every wired agent's config with the new key
```

## Idempotency and atomic writes

Every command is safe to re-run. The CLI compares the current state of each config file to the desired state before writing — if nothing has changed, nothing is written. This means:

* `xysq install` in a dotfiles bootstrap script is a fast no-op on every machine that's already set up.
* A crash mid-write leaves either the old config or the new config — never a partial. Writes go through a temp file + fsync + atomic rename.
* A second `xysq install` after a Ctrl-C resumes cleanly. There's no "repair" command needed.
