# Gadget Configuration Guide

This document describes how to configure the Gadget Code platform using YAML configuration files.

## Overview

Gadget Code uses YAML configuration files stored in standardized locations. This approach provides:

- **Centralized configuration**: All config in one place
- **Environment variable substitution**: Keep secrets in environment variables
- **System-wide or user-specific**: Install config in `~/.config/gadget/` or `/etc/gadget/`
- **No `.env` files**: Clean, validated configuration

## Configuration File Locations

Configuration files are searched in the following order (first match wins):

1. `~/.config/gadget/{app}.yaml` - User-specific configuration
2. `/etc/gadget/{app}.yaml` - System-wide configuration

### Files

- **gadget-code.yaml** - Configuration for the Gadget Code web server
- **gadget-drone.yaml** - Configuration for Gadget Drone worker processes

## Quick Start

### 1. Create Configuration Directory

```bash
mkdir -p ~/.config/gadget
```

### 2. Create Configuration Files

Copy the example configurations below and customize for your environment.

### 3. Set Environment Variables

For sensitive values, use environment variable substitution:

```bash
export DTP_JWT_SECRET="your-jwt-secret-here"
export DTP_USER_PASSWORD_SALT="your-password-salt-here"
export DTP_SESSION_SECRET="your-session-secret-here"
export GADGET_PLATFORM_KEY="your-platform-api-key-here"
```

### 4. Start the Applications

```bash
# Start Gadget Code web server
gadget-code-web

# Start Gadget Drone worker (from a workspace directory)
cd ~/my-gadget-workspace
gadget-drone
```

## gadget-code.yaml Reference

```yaml
# Basic settings
timezone: "America/New_York"

# Site information
site:
  company: "Your Company"
  companyShort: "YourCo"
  name: "Gadget Code"
  shortName: "Gadget"
  slogan: "Self-hosted Agentic Engineering Platform"
  description: "A self-hosted agentic development environment."
  domain: "code.example.com"
  domainKey: "code"
  host: "code.example.com:3443"

# Authentication (REQUIRED)
auth:
  jwtSecret: "${DTP_JWT_SECRET}" # Required
  passwordSalt: "${DTP_USER_PASSWORD_SALT}" # Required

# Session configuration (REQUIRED)
session:
  secret: "${DTP_SESSION_SECRET}" # Required
  trustProxy: true
  cookie:
    secure: true
    sameSite: "strict"

# MongoDB configuration
mongodb:
  host: "localhost:27017"
  database: "gadget-code"

# Redis configuration
redis:
  host: "localhost"
  port: 6379
  password: "${REDIS_PASSWORD}"
  keyPrefix: "gcode:"
  lazyConnect: false

# HTTPS configuration
https:
  enabled: true
  address: "localhost"
  port: 3443
  backlog: 128
  keyFile: "/path/to/ssl/key.pem"
  crtFile: "/path/to/ssl/cert.pem"
  uploadPath: "/tmp/gadget-code"

# Socket.IO configuration
socket:
  maxHttpBufferSize: 10485760 # 10MB

# Logging configuration
logging:
  console:
    enabled: true
  file:
    enabled: true
    path: "~/.local/state/gadget-code/logs" # Supports ~ for home directory
    name: "gadget-code"
  https:
    enabled: true
    name: "gadget-code.https.log"
    path: "~/.local/state/gadget-code/logs"
    format: "combined"
  levels:
    debug: true
    info: true
    warn: true

# Email configuration (optional)
email:
  enabled: false
  smtp:
    host: "smtp.example.com"
    port: 587
    secure: false
    from: "Gadget Code <noreply@example.com>"
    user: "smtp-user"
    password: "${SMTP_PASSWORD}"
    pool:
      enabled: true
      maxConnections: 5
      maxMessages: 100
  contact:
    to: "Support <support@example.com>"

# MinIO/S3 configuration (optional)
minio:
  endpoint: "localhost"
  port: 9000
  useSsl: false
  accessKey: "minio-access-key"
  secretKey: "${MINIO_SECRET_KEY}"
  buckets:
    uploads: "gadget-uploads"
    images: "gadget-images"
    videos: "gadget-videos"
    audios: "gadget-audios"

# User settings
user:
  signupEnabled: false
```

## gadget-drone.yaml Reference

```yaml
# Basic settings
timezone: "America/New_York"

# Platform connection (REQUIRED)
platform:
  baseUrl: "https://code.example.com:3443" # Required
  apiKey: "${GADGET_PLATFORM_KEY}" # Required

# Logging configuration
logging:
  console:
    enabled: true
  file:
    enabled: true
    path: "~/.local/state/gadget-drone/logs"
    name: "gadget-drone"
    maxWritesPerFile: 10000
    maxFiles: 10
  levels:
    debug: true
    info: true
    warn: true
```

## Environment Variable Substitution

Use `${VAR_NAME}` syntax to reference environment variables in your YAML config:

```yaml
auth:
  jwtSecret: "${DTP_JWT_SECRET}"
  passwordSalt: "${DTP_USER_PASSWORD_SALT}"
```

If an environment variable is referenced but not set, the application will fail to start with a clear error message.

## Log File Locations

By default, logs are written to XDG Base Directory spec locations:

- **gadget-code**: `~/.local/state/gadget-code/logs/`
- **gadget-drone**: `~/.local/state/gadget-drone/logs/`

You can override these in your configuration:

```yaml
logging:
  file:
    path: "/var/log/gadget-code"  # System-wide logs
    # or
    path: "~/.gadget-logs/code"   # Custom location in home
```

## Running the Applications

### Development Mode

When developing on the Gadget platform, use `pnpm` commands from the project directory:

```bash
# Start Gadget Code web server
cd /home/rob/projects/gadget/gadget-code
pnpm dev:backend

# Start Gadget Drone worker (from a workspace directory)
cd /home/rob/projects/gadget/gadget-drone
pnpm dev
```

Environment variables can be set inline or in a shell profile:

```bash
# Set required environment variables for gadget-code
export DTP_JWT_SECRET="your-jwt-secret"
export DTP_USER_PASSWORD_SALT="your-password-salt"
export DTP_SESSION_SECRET="your-session-secret"

# Set required environment variables for gadget-drone
export GADGET_PLATFORM_KEY="your-platform-api-key"
```

### Production Mode

For production deployment, the packages would be published to npm and installed globally:

```bash
# Install from npm (when published)
npm install -g gadget-code @gadget/drone

# Run from anywhere
gadget-code-web
gadget-drone
```

### Local Development with Global Commands

To test the global installation locally during development:

```bash
# From the monorepo root
cd /home/rob/projects/gadget

# Build all packages
pnpm -r build

# Link packages globally (creates symlinks)
cd gadget-code && pnpm link --global
cd ../gadget-drone && pnpm link --global

# Now you can run from anywhere
gadget-code-web
gadget-drone
```

**Note**: When using `pnpm link`, the binaries will reference the source code in your development directory. For a true production test, you would publish to npm or use `npm pack` to create tarballs.

### Multiple Drone Instances

You can run multiple `gadget-drone` instances on the same host, each in a different workspace directory:

```bash
# Terminal 1
cd ~/workspace-1
gadget-drone

# Terminal 2
cd ~/workspace-2
gadget-drone
```

Each drone will:

- Have its own unique workspace ID (stored in `.gadget/workspace.json`)
- Register separately with the platform
- Process work orders independently

**Note**: It is illegal to start more than one drone instance in the same directory.

## Migration from .env Files

If you have existing `.env` files, follow these steps:

### 1. Create YAML Configuration

Copy your `.env` values to the appropriate YAML file using the examples above.

### 2. Convert Variable Names

Map your old `.env` variable names to the new YAML structure:

| Old .env Variable        | New YAML Path        |
| ------------------------ | -------------------- |
| `DTP_JWT_SECRET`         | `auth.jwtSecret`     |
| `DTP_USER_PASSWORD_SALT` | `auth.passwordSalt`  |
| `DTP_SESSION_SECRET`     | `session.secret`     |
| `DTP_MONGODB_HOST`       | `mongodb.host`       |
| `DTP_REDIS_HOST`         | `redis.host`         |
| `GADGET_PLATFORM_URL`    | `platform.baseUrl`   |
| `GADGET_PLATFORM_KEY`    | `platform.gadgetKey` |

### 3. Set Environment Variables

Move sensitive values to environment variables (recommended):

```bash
# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.)
export DTP_JWT_SECRET="your-secret-here"
export DTP_USER_PASSWORD_SALT="your-salt-here"
export DTP_SESSION_SECRET="your-session-secret-here"
export GADGET_PLATFORM_KEY="your-platform-key-here"
```

### 4. Remove .env Files

Once you've verified the YAML configuration works:

```bash
# In gadget-code directory
rm .env

# In gadget-drone directory
rm .env
```

## Troubleshooting

### Configuration Not Found

If you see an error like:

```
Configuration file not found: gadget-code.yaml
```

Make sure you've created the configuration file in one of the supported locations:

```bash
# Check user config
ls -la ~/.config/gadget/

# Check system config
ls -la /etc/gadget/
```

### Environment Variable Not Set

If you see:

```
Environment variable DTP_JWT_SECRET is not set but referenced in config
```

Set the required environment variable:

```bash
export DTP_JWT_SECRET="your-secret-here"
```

Or add it to your shell profile for persistence.

### Invalid YAML Syntax

YAML files must be valid. Common issues:

- **Indentation**: Use spaces, not tabs
- **Quotes**: String values with special characters should be quoted
- **Colons**: Always followed by a space

Validate your YAML:

```bash
# Using Python
python -c "import yaml; yaml.safe_load(open('~/.config/gadget/gadget-code.yaml'))"

# Using Node.js
node -e "console.log(require('js-yaml').load(require('fs').readFileSync('~/.config/gadget/gadget-code.yaml', 'utf8')))"
```

## Security Best Practices

1. **Use environment variables for secrets**: Never store API keys, passwords, or secrets directly in YAML files
2. **Set appropriate file permissions**:
   ```bash
   chmod 600 ~/.config/gadget/gadget-code.yaml
   chmod 600 ~/.config/gadget/gadget-drone.yaml
   ```
3. **Use HTTPS in production**: Always enable HTTPS for the web server
4. **Restrict database access**: Configure MongoDB and Redis to only accept local connections
5. **Rotate secrets regularly**: Update JWT secrets, password salts, and API keys periodically
