# Mosaic Stack Comprehensive Installer Plan

## Executive Summary

This document outlines the plan for creating a comprehensive installation script for Mosaic Stack that "just works" across platforms, automatically installs all dependencies, detects the platform, and configures the system. The design is inspired by the OpenClaw installer pattern while addressing Mosaic Stack's unique requirements as a multi-tenant personal assistant platform with optional Docker deployment.

---

## 1. Current State Analysis

### 1.1 Existing Setup Script ([`scripts/setup.sh`](scripts/setup.sh))

**Strengths:**

- Interactive configuration wizard
- Platform detection (Debian, Arch, Fedora, macOS)
- Docker and native deployment modes
- Port conflict detection and resolution
- .env file management with value preservation
- Secret generation
- SSO/Authentik configuration
- Ollama integration options
- Traefik reverse proxy support

**Gaps:**

- No curl-able one-liner installation
- Missing automatic dependency installation for some platforms
- No WSL detection/handling
- No dry-run validation of full configuration
- Limited post-install validation
- No upgrade/migration path handling
- Missing verbose/debug mode
- No cleanup on failure
- PATH management not comprehensive

### 1.2 OpenClaw Installer Features to Adopt

| Feature                  | Description                                              | Priority |
| ------------------------ | -------------------------------------------------------- | -------- |
| curl-able one-liner      | `curl -fsSL URL \| bash` pattern                         | High     |
| Color output             | Consistent colored output with ACCENT/SUCCESS/WARN/ERROR | High     |
| Platform detection       | macOS, Linux, WSL detection                              | High     |
| Auto Homebrew            | Automatic Homebrew installation on macOS                 | Medium   |
| Node.js management       | NodeSource integration for Linux, Homebrew for macOS     | High     |
| npm permissions fix      | User-local npm global installs on Linux                  | Medium   |
| pnpm via corepack        | Corepack-first pnpm installation                         | High     |
| Git installation         | Automatic Git installation                               | Medium   |
| Multiple install methods | npm vs git checkout options                              | Low      |
| Dry-run mode             | Preview changes without execution                        | High     |
| Verbose mode             | Debug output with `set -x`                               | Medium   |
| Non-interactive mode     | CI/CD friendly automation                                | High     |
| TTY detection            | Graceful handling of piped input                         | High     |
| Temp file cleanup        | Trap-based cleanup on exit                               | High     |
| Downloader detection     | curl/wget abstraction                                    | Medium   |
| PATH warnings            | Alert user about PATH issues                             | Medium   |
| Post-install doctor      | Validation and migration                                 | High     |
| Fun taglines             | User-friendly messaging                                  | Low      |

---

## 2. Proposed Architecture

### 2.1 File Structure

```
scripts/
├── install.sh              # Main entry point (curl-able)
├── setup.sh                # Interactive configuration wizard (enhanced)
├── lib/
│   ├── common.sh           # Shared utilities (enhanced)
│   ├── platform.sh         # Platform detection functions
│   ├── dependencies.sh     # Dependency installation functions
│   ├── docker.sh           # Docker-specific functions
│   ├── native.sh           # Native deployment functions
│   └── validation.sh       # Post-install validation
└── commands/
    ├── doctor.sh           # Diagnostic and repair tool
    └── upgrade.sh          # Upgrade/migration handler
```

### 2.2 Installer Flow Diagram

```mermaid
flowchart TD
    A[curl/install.sh] --> B{Parse Arguments}
    B --> C{Help?}
    C -->|Yes| D[Show Usage]
    C -->|No| E{Dry Run?}

    E --> F[Detect Platform]
    F --> G[Detect Package Manager]

    G --> H{Install Method}
    H -->|docker| I[Check Docker]
    H -->|native| J[Check Node.js/pnpm]

    I --> K{Docker OK?}
    K -->|No| L[Install Docker]
    K -->|Yes| M[Check Docker Compose]
    L --> M

    J --> N{Node.js OK?}
    N -->|No| O[Install Node.js]
    N -->|Yes| P{pnpm OK?}
    O --> P
    P -->|No| Q[Install pnpm]
    P -->|Yes| R[Check PostgreSQL]
    Q --> R

    M --> S[Check Existing Config]
    R --> S

    S --> T{Has .env?}
    T -->|Yes| U[Load Existing Values]
    T -->|No| V[Interactive Config]
    U --> V

    V --> W[Generate Secrets]
    W --> X[Resolve Port Conflicts]
    X --> Y[Write .env]

    Y --> Z{Deployment Mode}
    Z -->|docker| AA[Docker Compose Up]
    Z -->|native| AB[Run Migrations]

    AA --> AC[Run Doctor]
    AB --> AC

    AC --> AD{All Checks Pass?}
    AD -->|Yes| AE[Show Success]
    AD -->|No| AF[Show Warnings]

    AE --> AG[Print Next Steps]
    AF --> AG
```

---

## 3. Detailed Component Design

### 3.1 Entry Point: `install.sh`

The main installer should support both quick-start and advanced usage:

```bash
# Usage patterns:
# Quick start (interactive):
curl -fsSL https://get.mosaicstack.dev | bash

# Non-interactive Docker deployment:
curl -fsSL https://get.mosaicstack.dev | bash -s -- --non-interactive --mode docker

# Dry run to preview:
curl -fsSL https://get.mosaicstack.dev | bash -s -- --dry-run --mode docker

# With all options:
curl -fsSL https://get.mosaicstack.dev | bash -s -- \
  --mode docker \
  --enable-sso \
  --bundled-authentik \
  --ollama-mode local \
  --base-url https://mosaic.example.com
```

**Command-line Options:**

| Option                     | Description                     | Default               |
| -------------------------- | ------------------------------- | --------------------- |
| `--mode`                   | Deployment mode: docker, native | interactive           |
| `--non-interactive`        | Skip all prompts                | false                 |
| `--dry-run`                | Preview without changes         | false                 |
| `--verbose`                | Enable debug output             | false                 |
| `--enable-sso`             | Enable Authentik SSO            | false                 |
| `--bundled-authentik`      | Use bundled Authentik           | false                 |
| `--external-authentik URL` | External Authentik URL          | -                     |
| `--ollama-mode`            | Ollama: local, remote, disabled | disabled              |
| `--ollama-url URL`         | Remote Ollama URL               | -                     |
| `--base-url URL`           | Mosaic base URL                 | http://localhost:3000 |
| `--profiles`               | Compose profiles to enable      | full                  |
| `--no-port-check`          | Skip port conflict detection    | false                 |
| `--skip-deps`              | Skip dependency installation    | false                 |
| `--help`                   | Show usage                      | -                     |

### 3.2 Platform Detection: `lib/platform.sh`

```bash
# Functions to implement:

detect_os()           # Returns: macos, debian, arch, fedora, linux, unknown
detect_package_manager()  # Returns: brew, apt, pacman, dnf, unknown
detect_wsl()          # Returns: WSL_DISTRO_NAME or empty
detect_init_system()  # Returns: systemd, openrc, launchd, unknown
get_os_name()         # Human-readable OS name
get_arch()            # Returns: x86_64, aarch64, armv7l
is_root()             # Check if running as root
maybe_sudo()          # Run with sudo only if needed
```

**Platform Support Matrix:**

| Platform      | Package Manager  | Init System | Node.js Source   |
| ------------- | ---------------- | ----------- | ---------------- |
| macOS         | Homebrew         | launchd     | Homebrew         |
| Ubuntu/Debian | apt              | systemd     | NodeSource       |
| Arch/Manjaro  | pacman           | systemd     | pacman           |
| Fedora/RHEL   | dnf              | systemd     | NodeSource       |
| WSL           | (host-dependent) | systemd\*   | (host-dependent) |

### 3.3 Dependency Management: `lib/dependencies.sh`

**Dependencies by Mode:**

**Docker Mode:**

- Docker Engine 24+
- Docker Compose (plugin or standalone)
- Git (for cloning if needed)

**Native Mode:**

- Node.js 22+
- pnpm 10+
- PostgreSQL 17+ (with pgvector)
- Valkey/Redis (optional)
- Git

**Optional Dependencies:**

- Ollama (for local LLM)
- OpenSSL (for secret generation)

**Installation Strategy:**

```bash
# macOS
install_homebrew()      # Auto-install Homebrew if missing
install_docker_macos()  # via Homebrew
install_node_macos()    # via Homebrew
install_pnpm()          # via corepack or npm

# Debian/Ubuntu
install_docker_debian() # via docker.com apt repo
install_node_debian()   # via NodeSource
install_postgres_debian() # via apt with pgvector

# Arch Linux
install_docker_arch()   # via pacman
install_node_arch()     # via pacman
install_postgres_arch() # via pacman with pgvector

# Fedora/RHEL
install_docker_fedora() # via dnf
install_node_fedora()   # via NodeSource
install_postgres_fedora() # via dnf
```

### 3.4 Docker Functions: `lib/docker.sh`

```bash
check_docker()           # Verify Docker is installed and accessible
check_docker_compose()   # Verify Docker Compose is available
check_docker_buildx()    # Verify buildx is available
fix_docker_permissions() # Add user to docker group
start_docker()           # Start Docker daemon if not running
docker_pull_images()     # Pre-pull all required images
docker_compose_up()      # Start services with health checks
docker_compose_down()    # Stop services
docker_logs()            # Tail logs for debugging
```

### 3.5 Configuration Generation

**Environment File Structure:**

The installer should generate a complete `.env` file based on:

1. **Existing values** (if `.env` exists)
2. **Command-line arguments**
3. **Interactive prompts** (if TTY available)
4. **Auto-detected defaults**

**Secret Generation:**

| Secret                       | Length | Method               |
| ---------------------------- | ------ | -------------------- |
| POSTGRES_PASSWORD            | 32     | openssl rand -base64 |
| JWT_SECRET                   | 32     | openssl rand -base64 |
| BETTER_AUTH_SECRET           | 32     | openssl rand -base64 |
| ENCRYPTION_KEY               | 32     | openssl rand -hex 32 |
| AUTHENTIK_SECRET_KEY         | 50     | openssl rand -base64 |
| AUTHENTIK_BOOTSTRAP_PASSWORD | 16     | openssl rand -base64 |
| COORDINATOR_API_KEY          | 32     | openssl rand -base64 |
| ORCHESTRATOR_API_KEY         | 32     | openssl rand -base64 |
| GITEA_WEBHOOK_SECRET         | 32     | openssl rand -hex 32 |

**URL Derivation:**

```bash
# Localhost mode
MOSAIC_BASE_URL=http://localhost:${WEB_PORT}
NEXT_PUBLIC_API_URL=http://localhost:${API_PORT}

# Domain mode (with Traefik)
MOSAIC_BASE_URL=https://${MOSAIC_WEB_DOMAIN}
NEXT_PUBLIC_API_URL=https://${MOSAIC_API_DOMAIN}

# IP mode (local network)
MOSAIC_BASE_URL=http://${LOCAL_IP}:${WEB_PORT}
NEXT_PUBLIC_API_URL=http://${LOCAL_IP}:${API_PORT}
```

### 3.6 Port Conflict Resolution

```bash
# Default ports
declare -A DEFAULT_PORTS=(
    [WEB_PORT]=3000
    [API_PORT]=3001
    [POSTGRES_PORT]=5432
    [VALKEY_PORT]=6379
    [AUTHENTIK_PORT_HTTP]=9000
    [AUTHENTIK_PORT_HTTPS]=9443
    [OLLAMA_PORT]=11434
    [TRAEFIK_HTTP_PORT]=80
    [TRAEFIK_HTTPS_PORT]=443
    [TRAEFIK_DASHBOARD_PORT]=8080
)

# Check if port is in use
check_port_in_use() {
    local port=$1
    # Try ss first, fall back to netstat, then lsof
}

# Suggest alternative port
suggest_alternative_port() {
    local base_port=$1
    # Try base_port+1, base_port+100, etc.
}
```

### 3.7 Post-Install Validation: `lib/validation.sh`

**Doctor Checks:**

```bash
# Docker mode checks
doctor_docker_running()      # Docker daemon is running
doctor_containers_healthy()  # All containers are healthy
doctor_database_connected()  # PostgreSQL is accessible
doctor_cache_connected()     # Valkey is accessible
doctor_api_responding()      # API health check passes
doctor_web_responding()      # Web frontend is accessible

# Native mode checks
doctor_node_version()        # Node.js version is sufficient
doctor_pnpm_version()        # pnpm is installed
doctor_postgres_running()    # PostgreSQL is running
doctor_migrations_applied()  # Database migrations are up to date
doctor_dependencies_installed()  # node_modules is complete

# General checks
doctor_env_complete()        # All required env vars are set
doctor_secrets_valid()       # Secrets are not placeholders
doctor_ports_available()     # Configured ports are available
doctor_disk_space()          # Sufficient disk space
```

### 3.8 Doctor Command: `scripts/commands/doctor.sh`

A standalone diagnostic tool that can be run after installation:

```bash
# Usage
./scripts/commands/doctor.sh              # Run all checks
./scripts/commands/doctor.sh --fix        # Attempt automatic fixes
./scripts/commands/doctor.sh --verbose    # Detailed output
./scripts/commands/doctor.sh --json       # JSON output for CI

# Exit codes
# 0: All checks passed
# 1: Some checks failed
# 2: Critical failure
```

---

## 4. User Experience Design

### 4.1 Banner and Branding

```
  __  __                 _       ____ _             _
 |  \/  | ___  ___  __ _(_) ___ / ___| |_ __ _  ___| | __
 | |\/| |/ _ \/ __|/ _` | |/ __|\___ | __/ _` |/ __| |/ /
 | |  | | (_) \__ \ (_| | | (__ ___/ | || (_| | (__|   <
 |_|  |_|\___/|___/\__,_|_|\___|____/ \__\__,_|\___|_|\_\

  Multi-Tenant Personal Assistant Platform

  Claws out, configs in — let's ship a calm, clean stack.
```

### 4.2 Progress Indicators

```
✓ Detected: macOS (brew)
✓ Docker: OK (version 27.0.0)
✓ Docker Compose: OK (version 2.28.0)
✓ Node.js: OK (v22.5.0)
⚠ Port 3000 is in use, using 3001
→ Generating secrets...
→ Writing .env file...
→ Starting services...
✓ All services healthy
```

### 4.3 Error Messages

```
✗ Docker is not running
  Start with: open -a Docker (macOS)
  Start with: sudo systemctl start docker (Linux)

✗ Port conflicts detected:
  - Web UI (3000): In use by process 12345 (node)
  - API (3001): In use by process 12346 (python)
  Run with --auto-ports to use alternative ports
```

### 4.4 Success Message

```
════════════════════════════════════════════════════════════
  Mosaic Stack is ready!
════════════════════════════════════════════════════════════

  Web UI:     http://localhost:3000
  API:        http://localhost:3001
  Database:   localhost:5432

  Next steps:
    1. Open http://localhost:3000 in your browser
    2. Create your first workspace
    3. Configure AI providers in Settings

  To stop:    docker compose down
  To restart: docker compose restart
  To view logs: docker compose logs -f

  Documentation: https://docs.mosaicstack.dev
  Support:       https://github.com/mosaicstack/stack/issues
```

---

## 5. Implementation Phases

### Phase 1: Core Infrastructure

- [ ] Create `install.sh` entry point with argument parsing
- [ ] Implement platform detection in `lib/platform.sh`
- [ ] Create dependency checking functions
- [ ] Add temp file cleanup and error handling
- [ ] Implement colored output system

### Phase 2: Dependency Installation

- [ ] Implement Homebrew auto-installation for macOS
- [ ] Implement Docker installation for all platforms
- [ ] Implement Node.js installation via NodeSource (Debian/Fedora)
- [ ] Implement pnpm installation via corepack
- [ ] Implement PostgreSQL installation with pgvector

### Phase 3: Configuration

- [ ] Enhance .env file generation
- [ ] Implement secret generation with proper entropy
- [ ] Add URL derivation logic for all access modes
- [ ] Implement port conflict detection and resolution
- [ ] Add configuration validation

### Phase 4: Service Management

- [ ] Implement Docker Compose service orchestration
- [ ] Add health check polling
- [ ] Implement database migration running
- [ ] Add service status reporting

### Phase 5: Validation and Doctor

- [ ] Create `scripts/commands/doctor.sh`
- [ ] Implement all diagnostic checks
- [ ] Add automatic fix capabilities
- [ ] Create JSON output mode for CI

### Phase 6: Polish and Testing

- [ ] Add comprehensive logging
- [ ] Test on all supported platforms
- [ ] Test upgrade scenarios
- [ ] Write documentation
- [ ] Create CI/CD integration examples

---

## 6. Testing Strategy

### 6.1 Platform Testing Matrix

| Platform | Version       | Docker | Native | CI             |
| -------- | ------------- | ------ | ------ | -------------- |
| macOS    | 14 (Sonoma)   | ✓      | ✓      | Manual         |
| macOS    | 13 (Ventura)  | ✓      | ✓      | Manual         |
| Ubuntu   | 24.04 LTS     | ✓      | ✓      | GitHub Actions |
| Ubuntu   | 22.04 LTS     | ✓      | ✓      | GitHub Actions |
| Debian   | 12 (Bookworm) | ✓      | ✓      | GitHub Actions |
| Arch     | Rolling       | ✓      | ✓      | Manual         |
| Fedora   | 40            | ✓      | ✓      | Manual         |
| WSL2     | Ubuntu        | ✓      | ✓      | Manual         |

### 6.2 Test Scenarios

1. **Fresh Installation**
   - No dependencies installed
   - Clean system

2. **Partial Dependencies**
   - Some dependencies already installed
   - Different versions

3. **Upgrade Scenario**
   - Existing .env file
   - Running containers

4. **Port Conflicts**
   - Common ports in use
   - All ports in use

5. **Error Recovery**
   - Network failures
   - Permission issues
   - Disk space issues

---

## 7. Security Considerations

### 7.1 Secret Handling

- Never log secrets to console or file
- Generate secrets with cryptographically secure random
- Validate secrets are not placeholders before starting
- Warn if default/weak secrets are detected

### 7.2 Network Security

- Download scripts over HTTPS only
- Verify TLS certificates
- Use specific version tags for Docker images
- Pin NodeSource repository version

### 7.3 File Permissions

- Set restrictive permissions on .env (600)
- Ensure secrets are not world-readable
- Validate file ownership

---

## 8. Documentation Requirements

### 8.1 README Updates

- Add installation section with curl command
- Document all command-line options
- Add troubleshooting section
- Include platform-specific notes

### 8.2 Inline Documentation

- Comment all functions with usage examples
- Document expected return values
- Include error codes

### 8.3 User Guide

- Step-by-step installation guide
- Configuration options explained
- Common issues and solutions
- Upgrade procedures

---

## 9. Open Questions

1. **Should we support Windows native installation?**
   - Current recommendation: WSL2 only
   - PowerShell version could be a future addition

2. **Should we support ARM platforms (Raspberry Pi)?**
   - Docker images would need ARM builds
   - Could be community-supported

3. **What is the upgrade strategy?**
   - In-place upgrade vs. migrate data
   - Database migration handling
   - Configuration file changes

4. **Should we provide an uninstaller?**
   - Clean up Docker volumes
   - Remove configuration files
   - Uninstall dependencies (optional)

---

## 10. Success Criteria

The installer is considered successful when:

1. ✅ A user can run `curl -fsSL https://get.mosaicstack.dev | bash` and have a working installation
2. ✅ All dependencies are automatically installed on supported platforms
3. ✅ Port conflicts are automatically detected and resolved
4. ✅ Secrets are automatically generated with proper entropy
5. ✅ The installation completes in under 5 minutes on a fresh system
6. ✅ Post-install validation confirms all services are healthy
7. ✅ Clear next steps are provided to the user
8. ✅ Non-interactive mode works for CI/CD pipelines
9. ✅ The doctor command can diagnose and fix common issues
10. ✅ Upgrade from previous versions preserves data and configuration

---

## Appendix A: Environment Variables Reference

See [`.env.example`](.env.example) for the complete list of configuration options.

## Appendix B: Docker Compose Profiles

| Profile           | Services     | Use Case            |
| ----------------- | ------------ | ------------------- |
| `full`            | All services | Development/Trial   |
| `database`        | PostgreSQL   | External cache/auth |
| `cache`           | Valkey       | External database   |
| `authentik`       | Authentik    | SSO enabled         |
| `ollama`          | Ollama       | Local LLM           |
| `traefik-bundled` | Traefik      | Reverse proxy       |
| `openbao`         | OpenBao      | Secrets management  |

## Appendix C: Related Files

- Current setup script: [`scripts/setup.sh`](scripts/setup.sh)
- Common utilities: [`scripts/lib/common.sh`](scripts/lib/common.sh)
- Docker Compose: [`docker-compose.yml`](docker-compose.yml)
- Environment example: [`.env.example`](.env.example)
- OpenClaw installer reference: [`examples/openclaw/install.sh`](examples/openclaw/install.sh)
