diff --git a/.env.example b/.env.example index 396d74e..96f3b7b 100644 --- a/.env.example +++ b/.env.example @@ -15,11 +15,19 @@ WEB_PORT=3000 # ====================== NEXT_PUBLIC_APP_URL=http://localhost:3000 NEXT_PUBLIC_API_URL=http://localhost:3001 +# Frontend auth mode: +# - real: Normal auth/session flow +# - mock: Local-only seeded user for FE development (blocked outside NODE_ENV=development) +# Use `mock` locally to continue FE work when auth flow is unstable. +# If omitted, web runtime defaults: +# - development -> mock +# - production -> real +NEXT_PUBLIC_AUTH_MODE=real # ====================== # PostgreSQL Database # ====================== -# Bundled PostgreSQL (when database profile enabled) +# Bundled PostgreSQL # SECURITY: Change POSTGRES_PASSWORD to a strong random password in production DATABASE_URL=postgresql://mosaic:REPLACE_WITH_SECURE_PASSWORD@postgres:5432/mosaic POSTGRES_USER=mosaic @@ -28,7 +36,7 @@ POSTGRES_DB=mosaic POSTGRES_PORT=5432 # External PostgreSQL (managed service) -# Disable 'database' profile and point DATABASE_URL to your external instance +# To use an external instance, update DATABASE_URL above # Example: DATABASE_URL=postgresql://user:pass@rds.amazonaws.com:5432/mosaic # PostgreSQL Performance Tuning (Optional) @@ -39,7 +47,7 @@ POSTGRES_MAX_CONNECTIONS=100 # ====================== # Valkey Cache (Redis-compatible) # ====================== -# Bundled Valkey (when cache profile enabled) +# Bundled Valkey VALKEY_URL=redis://valkey:6379 VALKEY_HOST=valkey VALKEY_PORT=6379 @@ -47,7 +55,7 @@ VALKEY_PORT=6379 VALKEY_MAXMEMORY=256mb # External Redis/Valkey (managed service) -# Disable 'cache' profile and point VALKEY_URL to your external instance +# To use an external instance, update VALKEY_URL above # Example: VALKEY_URL=redis://elasticache.amazonaws.com:6379 # Example with auth: VALKEY_URL=redis://:password@redis.example.com:6379 @@ -70,9 +78,9 @@ OIDC_ISSUER=https://auth.example.com/application/o/mosaic-stack/ OIDC_CLIENT_ID=your-client-id-here OIDC_CLIENT_SECRET=your-client-secret-here # Redirect URI must match what's configured in Authentik -# Development: http://localhost:3001/auth/callback/authentik -# Production: https://api.mosaicstack.dev/auth/callback/authentik -OIDC_REDIRECT_URI=http://localhost:3001/auth/callback/authentik +# Development: http://localhost:3001/auth/oauth2/callback/authentik +# Production: https://api.mosaicstack.dev/auth/oauth2/callback/authentik +OIDC_REDIRECT_URI=http://localhost:3001/auth/oauth2/callback/authentik # Authentik PostgreSQL Database AUTHENTIK_POSTGRES_USER=authentik @@ -116,6 +124,9 @@ JWT_EXPIRATION=24h # This is used by BetterAuth for session management and CSRF protection # Example: openssl rand -base64 32 BETTER_AUTH_SECRET=REPLACE_WITH_RANDOM_SECRET_MINIMUM_32_CHARS +# Optional explicit BetterAuth origin for callback/error URL generation. +# When empty, backend falls back to NEXT_PUBLIC_API_URL. +BETTER_AUTH_URL= # Trusted Origins (comma-separated list of additional trusted origins for CORS and auth) # These are added to NEXT_PUBLIC_APP_URL and NEXT_PUBLIC_API_URL automatically @@ -244,12 +255,16 @@ MOSAIC_API_DOMAIN=api.mosaic.local MOSAIC_WEB_DOMAIN=mosaic.local MOSAIC_AUTH_DOMAIN=auth.mosaic.local -# External Traefik network name (for upstream mode) +# External Traefik network name (for upstream mode and swarm) # Must match the network name of your existing Traefik instance TRAEFIK_NETWORK=traefik-public +TRAEFIK_DOCKER_NETWORK=traefik-public # TLS/SSL Configuration TRAEFIK_TLS_ENABLED=true +TRAEFIK_ENTRYPOINT=websecure +# Cert resolver name (leave empty if TLS is handled externally or using self-signed certs) +TRAEFIK_CERTRESOLVER= # For Let's Encrypt (production): TRAEFIK_ACME_EMAIL=admin@example.com # For self-signed certificates (development), leave TRAEFIK_ACME_EMAIL empty @@ -285,6 +300,15 @@ GITEA_WEBHOOK_SECRET=REPLACE_WITH_RANDOM_WEBHOOK_SECRET # The coordinator service uses this key to authenticate with the API COORDINATOR_API_KEY=REPLACE_WITH_RANDOM_API_KEY_MINIMUM_32_CHARS +# Anthropic API Key (used by coordinator for issue parsing) +# Get your API key from: https://console.anthropic.com/ +ANTHROPIC_API_KEY=REPLACE_WITH_ANTHROPIC_API_KEY + +# Coordinator tuning +COORDINATOR_POLL_INTERVAL=5.0 +COORDINATOR_MAX_CONCURRENT_AGENTS=10 +COORDINATOR_ENABLED=true + # ====================== # Rate Limiting # ====================== @@ -329,16 +353,34 @@ RATE_LIMIT_STORAGE=redis # ====================== # Matrix bot integration for chat-based control via Matrix protocol # Requires a Matrix account with an access token for the bot user -# MATRIX_HOMESERVER_URL=https://matrix.example.com -# MATRIX_ACCESS_TOKEN= -# MATRIX_BOT_USER_ID=@mosaic-bot:example.com -# MATRIX_CONTROL_ROOM_ID=!roomid:example.com -# MATRIX_WORKSPACE_ID=your-workspace-uuid +# Set these AFTER deploying Synapse and creating the bot account. # # SECURITY: MATRIX_WORKSPACE_ID must be a valid workspace UUID from your database. # All Matrix commands will execute within this workspace context for proper # multi-tenant isolation. Each Matrix bot instance should be configured for # a single workspace. +MATRIX_HOMESERVER_URL=http://synapse:8008 +MATRIX_ACCESS_TOKEN= +MATRIX_BOT_USER_ID=@mosaic-bot:matrix.example.com +MATRIX_SERVER_NAME=matrix.example.com +# MATRIX_CONTROL_ROOM_ID=!roomid:matrix.example.com +# MATRIX_WORKSPACE_ID=your-workspace-uuid + +# ====================== +# Matrix / Synapse Deployment +# ====================== +# Domains for Traefik routing to Matrix services +MATRIX_DOMAIN=matrix.example.com +ELEMENT_DOMAIN=chat.example.com + +# Synapse database (created automatically by synapse-db-init in the swarm compose) +SYNAPSE_POSTGRES_DB=synapse +SYNAPSE_POSTGRES_USER=synapse +SYNAPSE_POSTGRES_PASSWORD=REPLACE_WITH_SECURE_SYNAPSE_DB_PASSWORD + +# Image tags for Matrix services +SYNAPSE_IMAGE_TAG=latest +ELEMENT_IMAGE_TAG=latest # ====================== # Orchestrator Configuration @@ -350,6 +392,17 @@ RATE_LIMIT_STORAGE=redis # Health endpoints (/health/*) remain unauthenticated ORCHESTRATOR_API_KEY=REPLACE_WITH_RANDOM_API_KEY_MINIMUM_32_CHARS +# Runtime safety defaults (recommended for low-memory hosts) +MAX_CONCURRENT_AGENTS=2 +SESSION_CLEANUP_DELAY_MS=30000 +ORCHESTRATOR_QUEUE_NAME=orchestrator-tasks +ORCHESTRATOR_QUEUE_CONCURRENCY=1 +ORCHESTRATOR_QUEUE_MAX_RETRIES=3 +ORCHESTRATOR_QUEUE_BASE_DELAY_MS=1000 +ORCHESTRATOR_QUEUE_MAX_DELAY_MS=60000 +SANDBOX_DEFAULT_MEMORY_MB=256 +SANDBOX_DEFAULT_CPU_LIMIT=1.0 + # ====================== # AI Provider Configuration # ====================== @@ -363,11 +416,10 @@ AI_PROVIDER=ollama # For remote Ollama: http://your-ollama-server:11434 OLLAMA_MODEL=llama3.1:latest -# Claude API Configuration (when AI_PROVIDER=claude) -# OPTIONAL: Only required if AI_PROVIDER=claude +# Claude API Key +# Required only when AI_PROVIDER=claude. # Get your API key from: https://console.anthropic.com/ -# Note: Claude Max subscription users should use AI_PROVIDER=ollama instead -# CLAUDE_API_KEY=sk-ant-... +CLAUDE_API_KEY=REPLACE_WITH_CLAUDE_API_KEY # OpenAI API Configuration (when AI_PROVIDER=openai) # OPTIONAL: Only required if AI_PROVIDER=openai @@ -405,6 +457,9 @@ TTS_PREMIUM_URL=http://chatterbox-tts:8881/v1 TTS_FALLBACK_ENABLED=false TTS_FALLBACK_URL=http://openedai-speech:8000/v1 +# Whisper model for Speaches STT engine +SPEACHES_WHISPER_MODEL=Systran/faster-whisper-large-v3-turbo + # Speech Service Limits # Maximum upload file size in bytes (default: 25MB) SPEECH_MAX_UPLOAD_SIZE=25000000 @@ -439,28 +494,6 @@ MOSAIC_TELEMETRY_INSTANCE_ID=your-instance-uuid-here # Useful for development and debugging telemetry payloads MOSAIC_TELEMETRY_DRY_RUN=false -# ====================== -# Matrix Dev Environment (docker-compose.matrix.yml overlay) -# ====================== -# These variables configure the local Matrix dev environment. -# Only used when running: docker compose -f docker/docker-compose.yml -f docker/docker-compose.matrix.yml up -# -# Synapse homeserver -# SYNAPSE_CLIENT_PORT=8008 -# SYNAPSE_FEDERATION_PORT=8448 -# SYNAPSE_POSTGRES_DB=synapse -# SYNAPSE_POSTGRES_USER=synapse -# SYNAPSE_POSTGRES_PASSWORD=synapse_dev_password -# -# Element Web client -# ELEMENT_PORT=8501 -# -# Matrix bridge connection (set after running docker/matrix/scripts/setup-bot.sh) -# MATRIX_HOMESERVER_URL=http://localhost:8008 -# MATRIX_ACCESS_TOKEN= -# MATRIX_BOT_USER_ID=@mosaic-bot:localhost -# MATRIX_SERVER_NAME=localhost - # ====================== # Logging & Debugging # ====================== diff --git a/.env.prod.example b/.env.prod.example deleted file mode 100644 index 1b21644..0000000 --- a/.env.prod.example +++ /dev/null @@ -1,66 +0,0 @@ -# ============================================== -# Mosaic Stack Production Environment -# ============================================== -# Copy to .env and configure for production deployment - -# ====================== -# PostgreSQL Database -# ====================== -# CRITICAL: Use a strong, unique password -POSTGRES_USER=mosaic -POSTGRES_PASSWORD=REPLACE_WITH_SECURE_PASSWORD -POSTGRES_DB=mosaic -POSTGRES_SHARED_BUFFERS=256MB -POSTGRES_EFFECTIVE_CACHE_SIZE=1GB -POSTGRES_MAX_CONNECTIONS=100 - -# ====================== -# Valkey Cache -# ====================== -VALKEY_MAXMEMORY=256mb - -# ====================== -# API Configuration -# ====================== -API_PORT=3001 -API_HOST=0.0.0.0 - -# ====================== -# Web Configuration -# ====================== -WEB_PORT=3000 -NEXT_PUBLIC_API_URL=https://api.mosaicstack.dev - -# ====================== -# Authentication (Authentik OIDC) -# ====================== -OIDC_ISSUER=https://auth.diversecanvas.com/application/o/mosaic-stack/ -OIDC_CLIENT_ID=your-client-id -OIDC_CLIENT_SECRET=your-client-secret -OIDC_REDIRECT_URI=https://api.mosaicstack.dev/auth/callback/authentik - -# ====================== -# JWT Configuration -# ====================== -# CRITICAL: Generate a random secret (openssl rand -base64 32) -JWT_SECRET=REPLACE_WITH_RANDOM_SECRET -JWT_EXPIRATION=24h - -# ====================== -# Traefik Integration -# ====================== -# Set to true if using external Traefik -TRAEFIK_ENABLE=true -TRAEFIK_ENTRYPOINT=websecure -TRAEFIK_TLS_ENABLED=true -TRAEFIK_DOCKER_NETWORK=traefik-public -TRAEFIK_CERTRESOLVER=letsencrypt - -# Domain configuration -MOSAIC_API_DOMAIN=api.mosaicstack.dev -MOSAIC_WEB_DOMAIN=app.mosaicstack.dev - -# ====================== -# Optional: Ollama -# ====================== -# OLLAMA_ENDPOINT=http://ollama.diversecanvas.com:11434 diff --git a/.env.swarm.example b/.env.swarm.example deleted file mode 100644 index efa9d8a..0000000 --- a/.env.swarm.example +++ /dev/null @@ -1,161 +0,0 @@ -# ============================================== -# Mosaic Stack - Docker Swarm Configuration -# ============================================== -# Copy this file to .env for Docker Swarm deployment - -# ====================== -# Application Ports (Internal) -# ====================== -API_PORT=3001 -API_HOST=0.0.0.0 -WEB_PORT=3000 - -# ====================== -# Domain Configuration (Traefik) -# ====================== -# These domains must be configured in your DNS or /etc/hosts -MOSAIC_API_DOMAIN=api.mosaicstack.dev -MOSAIC_WEB_DOMAIN=mosaic.mosaicstack.dev -MOSAIC_AUTH_DOMAIN=auth.mosaicstack.dev - -# ====================== -# Web Configuration -# ====================== -# Use the Traefik domain for the API URL -NEXT_PUBLIC_APP_URL=http://mosaic.mosaicstack.dev -NEXT_PUBLIC_API_URL=http://api.mosaicstack.dev - -# ====================== -# PostgreSQL Database -# ====================== -DATABASE_URL=postgresql://mosaic:REPLACE_WITH_SECURE_PASSWORD@postgres:5432/mosaic -POSTGRES_USER=mosaic -POSTGRES_PASSWORD=REPLACE_WITH_SECURE_PASSWORD -POSTGRES_DB=mosaic -POSTGRES_PORT=5432 - -# PostgreSQL Performance Tuning -POSTGRES_SHARED_BUFFERS=256MB -POSTGRES_EFFECTIVE_CACHE_SIZE=1GB -POSTGRES_MAX_CONNECTIONS=100 - -# ====================== -# Valkey Cache -# ====================== -VALKEY_URL=redis://valkey:6379 -VALKEY_HOST=valkey -VALKEY_PORT=6379 -VALKEY_MAXMEMORY=256mb - -# Knowledge Module Cache Configuration -KNOWLEDGE_CACHE_ENABLED=true -KNOWLEDGE_CACHE_TTL=300 - -# ====================== -# Authentication (Authentik OIDC) -# ====================== -# NOTE: Authentik services are COMMENTED OUT in docker-compose.swarm.yml by default -# Uncomment those services if you want to run Authentik internally -# Otherwise, use external Authentik by configuring OIDC_* variables below - -# External Authentik Configuration (default) -OIDC_ENABLED=true -OIDC_ISSUER=https://auth.example.com/application/o/mosaic-stack/ -OIDC_CLIENT_ID=your-client-id-here -OIDC_CLIENT_SECRET=your-client-secret-here -OIDC_REDIRECT_URI=https://api.mosaicstack.dev/auth/callback/authentik - -# Internal Authentik Configuration (only needed if uncommenting Authentik services) -# Authentik PostgreSQL Database -AUTHENTIK_POSTGRES_USER=authentik -AUTHENTIK_POSTGRES_PASSWORD=REPLACE_WITH_SECURE_PASSWORD -AUTHENTIK_POSTGRES_DB=authentik - -# Authentik Server Configuration -AUTHENTIK_SECRET_KEY=REPLACE_WITH_RANDOM_SECRET_MINIMUM_50_CHARS -AUTHENTIK_ERROR_REPORTING=false -AUTHENTIK_BOOTSTRAP_PASSWORD=REPLACE_WITH_SECURE_PASSWORD -AUTHENTIK_BOOTSTRAP_EMAIL=admin@mosaicstack.dev -AUTHENTIK_COOKIE_DOMAIN=.mosaicstack.dev - -# ====================== -# JWT Configuration -# ====================== -JWT_SECRET=REPLACE_WITH_RANDOM_SECRET_MINIMUM_32_CHARS -JWT_EXPIRATION=24h - -# ====================== -# Encryption (Credential Security) -# ====================== -# Generate with: openssl rand -hex 32 -ENCRYPTION_KEY=REPLACE_WITH_64_CHAR_HEX_STRING_GENERATE_WITH_OPENSSL_RAND_HEX_32 - -# ====================== -# OpenBao Secrets Management -# ====================== -OPENBAO_ADDR=http://openbao:8200 -OPENBAO_PORT=8200 -# For development only - remove in production -OPENBAO_DEV_ROOT_TOKEN_ID=root - -# ====================== -# Ollama (Optional AI Service) -# ====================== -OLLAMA_ENDPOINT=http://ollama:11434 -OLLAMA_PORT=11434 -OLLAMA_EMBEDDING_MODEL=mxbai-embed-large - -# Semantic Search Configuration -SEMANTIC_SEARCH_SIMILARITY_THRESHOLD=0.5 - -# ====================== -# OpenAI API (Optional) -# ====================== -# OPENAI_API_KEY=sk-... - -# ====================== -# Application Environment -# ====================== -NODE_ENV=production - -# ====================== -# Gitea Integration (Coordinator) -# ====================== -GITEA_URL=https://git.mosaicstack.dev -GITEA_BOT_USERNAME=mosaic -GITEA_BOT_TOKEN=REPLACE_WITH_COORDINATOR_BOT_API_TOKEN -GITEA_BOT_PASSWORD=REPLACE_WITH_COORDINATOR_BOT_PASSWORD -GITEA_REPO_OWNER=mosaic -GITEA_REPO_NAME=stack -GITEA_WEBHOOK_SECRET=REPLACE_WITH_RANDOM_WEBHOOK_SECRET -COORDINATOR_API_KEY=REPLACE_WITH_RANDOM_API_KEY_MINIMUM_32_CHARS - -# ====================== -# Coordinator Service -# ====================== -ANTHROPIC_API_KEY=REPLACE_WITH_ANTHROPIC_API_KEY -COORDINATOR_POLL_INTERVAL=5.0 -COORDINATOR_MAX_CONCURRENT_AGENTS=10 -COORDINATOR_ENABLED=true - -# ====================== -# Rate Limiting -# ====================== -RATE_LIMIT_TTL=60 -RATE_LIMIT_GLOBAL_LIMIT=100 -RATE_LIMIT_WEBHOOK_LIMIT=60 -RATE_LIMIT_COORDINATOR_LIMIT=100 -RATE_LIMIT_HEALTH_LIMIT=300 -RATE_LIMIT_STORAGE=redis - -# ====================== -# Orchestrator Configuration -# ====================== -ORCHESTRATOR_API_KEY=REPLACE_WITH_RANDOM_API_KEY_MINIMUM_32_CHARS -CLAUDE_API_KEY=REPLACE_WITH_CLAUDE_API_KEY - -# ====================== -# Logging & Debugging -# ====================== -LOG_LEVEL=info -DEBUG=false diff --git a/.gitignore b/.gitignore index 1ce13dc..7e684f0 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,13 @@ yarn-error.log* # Orchestrator reports (generated by QA automation, cleaned up after processing) docs/reports/qa-automation/ + +# Repo-local orchestrator runtime artifacts +.mosaic/orchestrator/orchestrator.pid +.mosaic/orchestrator/state.json +.mosaic/orchestrator/tasks.json +.mosaic/orchestrator/matrix_state.json +.mosaic/orchestrator/logs/*.log +.mosaic/orchestrator/results/* +!.mosaic/orchestrator/logs/.gitkeep +!.mosaic/orchestrator/results/.gitkeep diff --git a/.mosaic/README.md b/.mosaic/README.md index 606f88a..3e13da9 100644 --- a/.mosaic/README.md +++ b/.mosaic/README.md @@ -4,12 +4,12 @@ This repository is attached to the machine-wide Mosaic framework. ## Load Order for Agents -1. `~/.mosaic/STANDARDS.md` +1. `~/.config/mosaic/STANDARDS.md` 2. `AGENTS.md` (this repository) 3. `.mosaic/repo-hooks.sh` (repo-specific automation hooks) ## Purpose -- Keep universal standards in `~/.mosaic` +- Keep universal standards in `~/.config/mosaic` - Keep repo-specific behavior in this repo - Avoid copying large runtime configs into each project diff --git a/.mosaic/orchestrator/config.json b/.mosaic/orchestrator/config.json new file mode 100644 index 0000000..ec50f98 --- /dev/null +++ b/.mosaic/orchestrator/config.json @@ -0,0 +1,18 @@ +{ + "enabled": true, + "transport": "matrix", + "matrix": { + "control_room_id": "", + "workspace_id": "", + "homeserver_url": "", + "access_token": "", + "bot_user_id": "" + }, + "worker": { + "runtime": "codex", + "command_template": "bash scripts/agent/orchestrator-worker.sh {task_file}", + "timeout_seconds": 7200, + "max_attempts": 1 + }, + "quality_gates": ["pnpm lint", "pnpm typecheck", "pnpm test"] +} diff --git a/.mosaic/orchestrator/logs/.gitkeep b/.mosaic/orchestrator/logs/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.mosaic/orchestrator/logs/.gitkeep @@ -0,0 +1 @@ + diff --git a/.mosaic/orchestrator/results/.gitkeep b/.mosaic/orchestrator/results/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.mosaic/orchestrator/results/.gitkeep @@ -0,0 +1 @@ + diff --git a/.mosaic/quality-rails.yml b/.mosaic/quality-rails.yml new file mode 100644 index 0000000..816ea24 --- /dev/null +++ b/.mosaic/quality-rails.yml @@ -0,0 +1,10 @@ +enabled: false +template: "" + +# Set enabled: true and choose one template: +# - typescript-node +# - typescript-nextjs +# - monorepo +# +# Apply manually: +# ~/.config/mosaic/bin/mosaic-quality-apply --template