# Configuration Management

Styrene uses persistent configuration stored in `~/.styrene/` for both its own settings and Reticulum mesh networking.

## Directory Structure

```
~/.styrene/
├── config.yaml           # Styrene configuration
├── operator.key          # Your mesh identity (keep private!)
├── data/                 # Device specs, fleet data
├── cache/                # Temporary files
└── logs/                 # Application logs

~/.config/reticulum/      # Reticulum configuration (XDG-compliant)
└── config                # RNS network config

OR

~/.reticulum/             # Reticulum configuration (legacy)
└── config                # RNS network config
```

## Configuration Priority

### Styrene Config Loading Order

1. **CLI arguments** (highest priority)
2. **Environment variables** (not yet implemented)
3. **Config file** (`~/.styrene/config.yaml`)
4. **Defaults** (built-in fallbacks)

### Reticulum Config Detection

1. **Existing RNS config** (if found at standard locations)
2. **Generate from Styrene settings** (if no RNS config exists)
3. **Temporary config** (fallback if generation fails)

## First Run Behavior

When you first run Styrene:

1. **Creates `~/.styrene/` directory**
2. **Generates operator identity** (`~/.styrene/operator.key`)
3. **Checks for Reticulum config**:
   - If found: uses existing config
   - If not found: generates RNS config from Styrene defaults
4. **Saves Styrene config** if CLI args were used

## CLI Configuration

### Override Settings via CLI

```bash
# Set deployment mode
styrene --mode hub

# Configure server port
styrene --mode hub --port 4242

# Add peer connections
styrene --peer home.vanderlyn.house:4242
styrene --peer hub1:4242 --peer hub2:4965

# Enable headless mode with API
styrene --headless --api-port 8000

# Combine multiple flags
styrene --mode hub --port 4242 --api-port 8000 --headless
```

### Persistence of CLI Arguments

**CLI arguments are saved to `~/.styrene/config.yaml`** on first use.

This means:
- Run `styrene --mode hub --port 4242` once
- Settings are persisted to config file
- Next time, just run `styrene` and it uses saved settings

**To reset to defaults**:
```bash
rm ~/.styrene/config.yaml
```

## Configuration File Format

### Example: `~/.styrene/config.yaml`

```yaml
# Deployment mode
reticulum:
  mode: hub              # standalone, hub, or peer
  announce_interval: 300 # Seconds between announces

  # Network interfaces
  interfaces:
    auto: true           # Local UDP discovery

    server:
      enabled: true      # Accept TCP connections
      listen_ip: 0.0.0.0
      port: 4242

    peers:               # Connect to these hubs
      - host: home.vanderlyn.house
        port: 4242
        name: Home Hub

# HTTP API
api:
  enabled: true
  host: 0.0.0.0
  port: 8000

# Run without TUI
advanced:
  headless: true
```

See [`docs/config-example.yaml`](config-example.yaml) for all available options.

## Reticulum Config Generation

When Styrene generates Reticulum config, it creates:

```ini
# ~/.config/reticulum/config (or ~/.reticulum/config)

[reticulum]
enable_transport = true    # If mode = hub
share_instance = true

[interfaces]
[[AutoInterface]]
type = AutoInterface
enabled = true

# If mode = hub
[[TCP Server Interface]]
type = TCPServerInterface
enabled = true
listen_ip = 0.0.0.0
listen_port = 4242

# For each peer
[[Peer Name]]
type = TCPClientInterface
enabled = true
target_host = peer.host.com
target_port = 4242
```

**Manual Editing**: You can edit this file manually. Styrene will respect existing RNS config unless you use `--mode` or `--peer` CLI flags, which regenerate it.

## Using Existing Reticulum Config

If you already have Reticulum configured (e.g., from NomadNet or other tools):

1. **Styrene detects existing config** at standard locations:
   - `/etc/reticulum/config` (system-wide)
   - `~/.config/reticulum/config` (XDG)
   - `~/.reticulum/config` (legacy)

2. **Uses existing config** for initialization

3. **No generation or overwriting** (unless you explicitly use CLI flags)

**Example**: If you've manually configured interfaces in RNS config, Styrene will use those interfaces instead of its own settings.

## Configuration Scenarios

### Scenario 1: Fresh Install, No RNS Config

```bash
# First run
styrene

# What happens:
# 1. Creates ~/.styrene/
# 2. Generates ~/.styrene/operator.key
# 3. No RNS config found
# 4. Generates ~/.config/reticulum/config with default settings:
#    - mode: standalone
#    - enable_transport: false
#    - interfaces: AutoInterface only
# 5. Initializes RNS with generated config
```

### Scenario 2: Fresh Install, Set Hub Mode

```bash
# First run with mode flag
styrene --mode hub

# What happens:
# 1. Creates ~/.styrene/
# 2. Generates ~/.styrene/operator.key
# 3. Saves config with mode: hub to ~/.styrene/config.yaml
# 4. Generates ~/.config/reticulum/config with hub settings:
#    - enable_transport: true
#    - TCPServerInterface on port 4242
# 5. Initializes RNS as transport node
```

### Scenario 3: Existing RNS Config (from NomadNet)

```bash
# You already have ~/.config/reticulum/config from NomadNet
styrene

# What happens:
# 1. Creates ~/.styrene/ (Styrene-specific files)
# 2. Generates ~/.styrene/operator.key
# 3. Detects existing RNS config at ~/.config/reticulum/config
# 4. Uses existing RNS config (respects your manual settings)
# 5. Initializes RNS with your existing interfaces
```

### Scenario 4: CLI Override with Existing RNS Config

```bash
# You have RNS config but want Styrene-specific settings
styrene --mode hub --peer home.vanderlyn.house:4242

# What happens:
# 1. CLI args take priority
# 2. Saves Styrene config to ~/.styrene/config.yaml
# 3. REGENERATES ~/.config/reticulum/config with new settings
# 4. Your manual RNS config is overwritten
#    (back it up first if you want to preserve it!)
```

**Warning**: Using `--mode`, `--port`, or `--peer` CLI flags will **overwrite existing RNS config**. If you have manually configured Reticulum, avoid these flags or back up your config first.

## Operator Identity

Your mesh identity is stored in `~/.styrene/operator.key`.

**Security**:
- Contains private X25519/Ed25519 keys
- Uniquely identifies you on the mesh
- **Keep this file private!**
- File permissions: `600` (owner read/write only)

**Backup**: Copy `~/.styrene/operator.key` to a secure location. If lost, you'll get a new identity and need to re-announce to the mesh.

**Restore**: Copy backed-up `operator.key` to `~/.styrene/operator.key` before running Styrene.

## Environment Variables

(Future feature - not yet implemented)

```bash
export STYRENE_MODE=hub
export STYRENE_PORT=4242
export STYRENE_HEADLESS=true

styrene  # Uses environment variables
```

## Configuration Validation

Styrene validates configuration on load:

- **Paths exist** (SSH keys, fleet repos)
- **Ports valid** (1-65535)
- **Modes valid** (standalone, hub, peer)
- **LXMF addresses** (32 hex characters)

**Validation errors** are logged but don't prevent startup (falls back to defaults).

## Debugging Configuration

### Show Current Config

```bash
# Read config file
cat ~/.styrene/config.yaml

# Check Reticulum config
cat ~/.config/reticulum/config
# OR
cat ~/.reticulum/config
```

### Verify Identity

```bash
# Check operator identity exists
ls -lh ~/.styrene/operator.key

# Should show: -rw------- (600 permissions)
```

### Test Configuration

```bash
# Run with debug logging
styrene --mode standalone

# Check logs
tail -f ~/.styrene/logs/styrene.log

# Look for:
# - "Operator identity ready"
# - "Using existing Reticulum config" OR "Generated Reticulum config"
# - "RNS service initialized"
```

## Configuration Tips

### Tip 1: Incremental Setup

Start simple, add complexity as needed:

```bash
# Day 1: Run locally
styrene

# Day 2: Add remote access
styrene --mode hub --api-port 8000

# Day 3: Connect to peers
styrene --mode hub --peer external-hub:4242
```

### Tip 2: Separate Configs for Different Contexts

Use different config files for different scenarios:

```bash
# Laptop (standalone)
cp ~/.styrene/config.yaml ~/.styrene/config-laptop.yaml

# Server (hub)
styrene --mode hub
cp ~/.styrene/config.yaml ~/.styrene/config-server.yaml

# Switch between them
cp ~/.styrene/config-laptop.yaml ~/.styrene/config.yaml
styrene
```

(Future: `--config` flag to specify config file)

### Tip 3: Version Control

**DO**:
- Version control your `config.yaml` (settings)
- Document your deployment in git

**DON'T**:
- Version control `operator.key` (identity - keep private!)
- Commit RNS config if it contains sensitive info

## Troubleshooting

### "RNS service initialization failed"

**Cause**: RNS library not installed

**Fix**:
```bash
pip install rns
```

### "Could not create RNS config: Permission denied"

**Cause**: No write access to `~/.config/reticulum/`

**Fix**:
```bash
mkdir -p ~/.config/reticulum
chmod 700 ~/.config/reticulum
```

### "Config validation failed"

**Cause**: Invalid values in `~/.styrene/config.yaml`

**Fix**:
```bash
# Reset to defaults
rm ~/.styrene/config.yaml
styrene  # Regenerates defaults
```

### "Transport not enabled" (when expecting hub mode)

**Cause**: Mode not set correctly

**Fix**:
```bash
# Verify mode in config
grep "mode:" ~/.styrene/config.yaml

# Should show: mode: hub
# If not, set it:
styrene --mode hub
```

## See Also

- [Deployment Modes](deployment-modes.md) - Mode-specific configuration
- [Example Config](config-example.yaml) - Full config with comments
- [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/) - RNS configuration reference
