Spaces:
Sleeping
Sleeping
| """ | |
| Atom CLI - Init command for Personal Edition setup. | |
| Creates initial configuration for Personal Edition: | |
| - .env file with Personal defaults (SQLite) | |
| - data/ directory for local storage | |
| - Database initialization | |
| - First run wizard | |
| """ | |
| import os | |
| import sys | |
| import click | |
| import logging | |
| from pathlib import Path | |
| from datetime import datetime | |
| # Add backend to path for imports | |
| sys.path.insert(0, str(Path(__file__).parent.parent)) | |
| logger = logging.getLogger(__name__) | |
| def init(force: bool, edition: str, database_url: str, no_input: bool): | |
| """ | |
| Initialize Atom Personal Edition configuration. | |
| Creates .env file with Personal Edition defaults: | |
| - SQLite database (./data/atom.db) | |
| - Local filesystem storage | |
| - Minimal feature set | |
| **Examples:** | |
| atom init # Interactive setup | |
| atom init --edition personal # Personal Edition | |
| atom init --edition enterprise # Enterprise Edition | |
| atom init --force # Overwrite existing | |
| atom init --no-input # Use all defaults | |
| **Enterprise Edition:** | |
| atom init --edition enterprise \\ | |
| --database-url "postgresql://user:pass@localhost/atom" | |
| """ | |
| click.echo(click.style("Atom Initialization", bold=True)) | |
| click.echo("=" * 50) | |
| # Check if already initialized | |
| env_file = Path(".env") | |
| if env_file.exists() and not force: | |
| click.echo(click.style("Configuration already exists!", fg="yellow")) | |
| click.echo("Use --force to overwrite") | |
| # Show current status | |
| from core.package_feature_service import get_package_feature_service | |
| service = get_package_feature_service() | |
| click.echo("") | |
| click.echo(f"Current Edition: {service.edition.value}") | |
| click.echo(f"Database: {os.getenv('DATABASE_URL', 'Not configured')}") | |
| raise SystemExit(1) | |
| # Edition-specific defaults | |
| if edition == "personal": | |
| _init_personal_edition(database_url, no_input) | |
| else: | |
| _init_enterprise_edition(database_url, no_input, force) | |
| # Success message | |
| click.echo("") | |
| click.echo(click.style("Initialization complete!", fg="green", bold=True)) | |
| click.echo("") | |
| click.echo("Next steps:") | |
| click.echo(" 1. Edit .env and add your API keys:") | |
| click.echo(" OPENAI_API_KEY=sk-...") | |
| click.echo(" ANTHROPIC_API_KEY=sk-ant-...") | |
| click.echo("") | |
| click.echo(" 2. Start Atom:") | |
| click.echo(" atom start") | |
| click.echo("") | |
| click.echo(f" 3. Open dashboard:") | |
| click.echo(" http://localhost:8000") | |
| def _init_personal_edition(database_url: str, no_input: bool) -> None: | |
| """Initialize Personal Edition configuration.""" | |
| click.echo("") | |
| click.echo(click.style("Setting up Personal Edition...", fg="blue")) | |
| # Create data directory | |
| data_dir = Path("data") | |
| data_dir.mkdir(exist_ok=True) | |
| click.echo(f" Created data directory: {data_dir}") | |
| # Generate encryption keys | |
| import secrets | |
| encryption_key = secrets.token_urlsafe(32) | |
| jwt_secret = secrets.token_urlsafe(32) | |
| # Set Personal Edition defaults | |
| env_content = f"""# Atom Personal Edition Configuration | |
| # Generated: {datetime.now().isoformat()} | |
| # Edition | |
| ATOM_EDITION=personal | |
| # Server | |
| PORT=8000 | |
| HOST=0.0.0.0 | |
| WORKERS=1 | |
| # Database (SQLite - Personal Edition default) | |
| DATABASE_URL=sqlite:///./data/atom.db | |
| # Encryption Keys (auto-generated) | |
| BYOK_ENCRYPTION_KEY={encryption_key} | |
| JWT_SECRET_KEY={jwt_secret} | |
| # LLM Providers (add your keys) | |
| OPENAI_API_KEY= | |
| ANTHROPIC_API_KEY= | |
| DEEPSEEK_API_KEY= | |
| # Vector Embeddings (local - Personal Edition) | |
| EMBEDDING_PROVIDER=fastembed | |
| FASTEMBED_MODEL=BAAI/bge-small-en-v1.5 | |
| LANCEDB_PATH=./data/lancedb | |
| # Agent Governance | |
| AGENT_MATURITY_DEFAULT=STUDENT | |
| MAX_CONCURRENT_AGENTS=3 | |
| # Logging | |
| LOG_LEVEL=INFO | |
| STRUCTLOG_LEVEL=INFO | |
| # Feature Flags (Personal Edition) | |
| ATOM_MULTI_USER_ENABLED=false | |
| ATOM_MONITORING_ENABLED=false | |
| ATOM_SSO_ENABLED=false | |
| """ | |
| # Use custom database URL if provided | |
| if database_url: | |
| env_content = env_content.replace( | |
| "DATABASE_URL=sqlite:///./data/atom.db", | |
| f"DATABASE_URL={database_url}" | |
| ) | |
| # Write .env file | |
| env_file = Path(".env") | |
| env_file.write_text(env_content) | |
| click.echo(f" Created .env file (Personal Edition)") | |
| # Create subdirectories | |
| (data_dir / "lancedb").mkdir(exist_ok=True) | |
| (data_dir / "uploads").mkdir(exist_ok=True) | |
| click.echo(f" Created storage directories") | |
| # Show database info | |
| db_url = database_url or "sqlite:///./data/atom.db" | |
| click.echo(f" Database: {db_url}") | |
| def _init_enterprise_edition(database_url: str, no_input: bool, force: bool) -> None: | |
| """Initialize Enterprise Edition configuration.""" | |
| click.echo("") | |
| click.echo(click.style("Setting up Enterprise Edition...", fg="blue")) | |
| # Prompt for database URL if not provided | |
| if not database_url and not no_input: | |
| click.echo("") | |
| click.echo("Enterprise Edition requires PostgreSQL.") | |
| database_url = click.prompt( | |
| "Enter PostgreSQL database URL", | |
| default="postgresql://atom:atom@localhost:5432/atom" | |
| ) | |
| if not database_url: | |
| click.echo(click.style("Error: Database URL required for Enterprise", fg="red"), err=True) | |
| raise SystemExit(1) | |
| # Create data directory | |
| data_dir = Path("data") | |
| data_dir.mkdir(exist_ok=True) | |
| click.echo(f" Created data directory: {data_dir}") | |
| # Generate encryption keys | |
| import secrets | |
| encryption_key = secrets.token_urlsafe(32) | |
| jwt_secret = secrets.token_urlsafe(32) | |
| # Set Enterprise Edition defaults | |
| env_content = f"""# Atom Enterprise Edition Configuration | |
| # Generated: {datetime.now().isoformat()} | |
| # Edition | |
| ATOM_EDITION=enterprise | |
| # Server | |
| PORT=8000 | |
| HOST=0.0.0.0 | |
| WORKERS=4 | |
| # Database (PostgreSQL - Enterprise Edition required) | |
| DATABASE_URL={database_url} | |
| # Encryption Keys (auto-generated) | |
| BYOK_ENCRYPTION_KEY={encryption_key} | |
| JWT_SECRET_KEY={jwt_secret} | |
| # LLM Providers | |
| OPENAI_API_KEY= | |
| ANTHROPIC_API_KEY= | |
| DEEPSEEK_API_KEY= | |
| # Vector Embeddings (OpenAI for Enterprise) | |
| EMBEDDING_PROVIDER=openai | |
| OPENAI_EMBEDDING_MODEL=text-embedding-3-small | |
| LANCEDB_PATH=./data/lancedb | |
| # Agent Governance | |
| AGENT_MATURITY_DEFAULT=STUDENT | |
| MAX_CONCURRENT_AGENTS=10 | |
| # Multi-User (Enterprise) | |
| ATOM_MULTI_USER_ENABLED=true | |
| ATOM_WORKSPACE_ISOLATION=true | |
| # SSO (Enterprise) | |
| ATOM_SSO_ENABLED=false | |
| # SSO_PROVIDER=okta|auth0|saml | |
| # OKTA_DOMAIN= | |
| # OKTA_CLIENT_ID= | |
| # AUTH0_DOMAIN= | |
| # AUTH0_CLIENT_ID= | |
| # Monitoring (Enterprise) | |
| ATOM_MONITORING_ENABLED=true | |
| PROMETHEUS_ENABLED=true | |
| PROMETHEUS_PORT=9090 | |
| # Logging | |
| LOG_LEVEL=INFO | |
| STRUCTLOG_LEVEL=INFO | |
| STRUCTLOG_JSON=true | |
| # Redis (Enterprise - for multi-user pub/sub) | |
| REDIS_URL=redis://localhost:6379/0 | |
| # Audit Trail (Enterprise) | |
| ATOM_AUDIT_TRAIL_ENABLED=true | |
| AUDIT_LOG_RETENTION_DAYS=90 | |
| # Rate Limiting (Enterprise) | |
| ATOM_RATE_LIMITING_ENABLED=true | |
| RATE_LIMIT_PER_MINUTE=60 | |
| """ | |
| # Write .env file | |
| env_file = Path(".env") | |
| env_file.write_text(env_content) | |
| click.echo(f" Created .env file (Enterprise Edition)") | |
| # Create subdirectories | |
| (data_dir / "lancedb").mkdir(exist_ok=True) | |
| (data_dir / "uploads").mkdir(exist_ok=True) | |
| (data_dir / "audit").mkdir(exist_ok=True) | |
| click.echo(f" Created storage directories") | |
| # Warning about PostgreSQL | |
| click.echo("") | |
| click.echo(click.style("PostgreSQL Setup Required:", fg="yellow")) | |
| click.echo(" 1. Ensure PostgreSQL is installed and running") | |
| click.echo(" 2. Create database: createdb atom") | |
| click.echo(" 3. Or use connection string to existing database") | |
| click.echo("") | |
| click.echo("Current DATABASE_URL:") | |
| click.echo(f" {database_url}") | |
| def register_init_command(cli_group): | |
| """Register init command with CLI group.""" | |
| cli_group.add_command(init) | |