# Map
## Actors
- **User/Agent** → invokes `ax` CLI
- **ax binary** → parses args, resolves auth, makes API calls, renders output
- **X API v2** (`api.x.com`) → Twitter/X backend
- **Token store** (`$XDG_DATA_HOME/agent-x/tokens.json`) → encrypted OAuth 2.0 tokens
- **oauth.cli.city** (`https://oauth.cli.city/`) → static site catching OAuth redirects, encodes callback params as base64 token
## Data flows
```
User/Agent
│
├─ ax tweet post "text"
│ → resolve_auth() → AuthProvider
│ → XClient.post("/tweets", body)
│ → X API v2 (POST https://api.x.com/2/tweets)
│ → Response → Tweet → render(mode) → stdout
│
├─ ax auth login
│ → generate PKCE challenge
│ → bind 127.0.0.1:{port}
│ → open browser → x.com/i/oauth2/authorize
│ → receive callback → exchange code → token
│ → encrypt → $XDG_DATA_HOME/agent-x/tokens.json
│
├─ ax auth login --no-browser (non-interactive)
│ → generate PKCE challenge
│ → save PendingAuth → $XDG_STATE_HOME/agent-x/pending_auth.json
│ → print auth URL → exit
│ → user authorizes → x.com redirects → oauth.cli.city
│ → static site shows base64 token → user copies
│
├─ ax auth callback <token>
│ → decode base64 → {code, state}
│ → load PendingAuth → validate state
│ → exchange code → token
│ → encrypt → $XDG_DATA_HOME/agent-x/tokens.json
│ → delete pending_auth.json
│
└─ ax auth status
→ resolve_auth() → AuthProvider.method_name()
→ load_tokens() → expiry, scopes
→ render(mode) → stdout
```
## Port map
| 21847 (default) | OAuth 2.0 PKCE callback server (configurable via `--port`) |
## File locations
| `$XDG_DATA_HOME/agent-x/tokens.json` | Encrypted OAuth 2.0 tokens (0600) |
| `$XDG_STATE_HOME/agent-x/pending_auth.json` | Encrypted pending auth state (0600, 10 min TTL) |
## Environment variables
| `NO_DNA` | Enable agent-friendly mode (JSON output, no interactivity) |
| `X_CLIENT_ID` | OAuth 2.0 client ID (required for `ax auth login`) |
| `X_API_KEY` | OAuth 1.0a consumer key |
| `X_API_SECRET` | OAuth 1.0a consumer secret |
| `X_ACCESS_TOKEN` | OAuth 1.0a access token |
| `X_ACCESS_TOKEN_SECRET` | OAuth 1.0a access token secret |
| `X_BEARER_TOKEN` | Bearer token (read-only) |
| `NO_COLOR` | Disable terminal colors (respected by `colored` crate) |