#!/usr/bin/env nu # Install all syntaxis targets with configurations and wrapper scripts # # Usage: # ./scripts/install-all-targets.nu # ./scripts/install-all-targets.nu --config-dir ~/.config/syntaxis # ./scripts/install-all-targets.nu --install-dir /usr/local/bin # # Creates: # - Configuration files for each target # - Wrapper scripts to run with proper configs # - Data directories for persistence use std log def main [ --config-dir: string = "" # Where to place config files (default: ~/.config/syntaxis) --install-dir: string = "" # Where to install binaries (default: ~/.local/bin) --data-dir: string = "" # Where to store data/databases (default: ~/.local/share/syntaxis) --skip-api # Skip syntaxis-api installation --skip-tui # Skip syntaxis-tui installation --skip-dashboard # Skip syntaxis-dashboard installation ] { log info "🚀 Installing Lifecycle Targets..." print "" # Determine directories let config_dir = if ($config_dir == "") { $"($env.HOME)/.config/syntaxis" } else { $config_dir } let install_dir = if ($install_dir == "") { $"($env.HOME)/.local/bin" } else { $install_dir } let data_dir = if ($data_dir == "") { $"($env.HOME)/.local/share/syntaxis" } else { $data_dir } let project_root = pwd # Create directories mkdir $config_dir | ignore mkdir $install_dir | ignore mkdir $data_dir | ignore log info $"✓ Created directories in ($config_dir)" # Install syntaxis-api (API) if not $skip_api { install_api $config_dir $install_dir $data_dir $project_root } # Install syntaxis-tui if not $skip_tui { install_tui $config_dir $install_dir $data_dir $project_root } # Install syntaxis-dashboard if not $skip_dashboard { install_dashboard $config_dir $install_dir $data_dir $project_root } print "" print $"(ansi green)✅ Installation Complete!(ansi reset)" print "" print "Configuration files:" print $" ($config_dir)/syntaxis-api.toml" print $" ($config_dir)/syntaxis-tui.toml" print $" ($config_dir)/syntaxis-dashboard.toml" print "" print "Wrapper scripts (binaries resolved from PATH):" print $" ($install_dir)/syntaxis-api.sh" print $" ($install_dir)/syntaxis-tui.sh" print $" ($install_dir)/syntaxis-dashboard.sh" print "" print "Data directory:" print $" ($data_dir)" print "" print "Quick Start:" print $" # Terminal 1 - Start API server" print $" syntaxis-api.sh" print "" print $" # Terminal 2 - Start Dashboard" print $" syntaxis-dashboard.sh" print "" print $" # Terminal 3 - Start TUI" print $" syntaxis-tui.sh" print "" } def install_api [config_dir, install_dir, data_dir, project_root] { log info "📦 Installing syntaxis-api..." let binary = $"($project_root)/target/release/syntaxis-api" if not ($binary | path exists) { log warn $"Binary not found in: ($binary)" log info " Binary will be resolved from PATH (ensure 'cargo install' was run)" } let config_file = $"($config_dir)/syntaxis-api.toml" let features_dir = $"($config_dir)/configs/features" # Create features directory structure mkdir $features_dir | ignore log info $"✓ Created features directory: ($features_dir)" # Create MAIN config file (Tier 1) let config_content = $"# Lifecycle Server Configuration (Main) [server] host = \"127.0.0.1\" port = 3000 database_path = \"($data_dir)/syntaxis.db\" cors_enabled = true log_level = \"info\" public_files_path = \"./public\" [server.tls] enabled = false # cert_path = \"/path/to/cert.pem\" # key_path = \"/path/to/key.pem\" # Feature Flags - Tier 2 features [server.features.database] enabled = true [server.features.health] enabled = true [server.features.metrics] enabled = false [server.features.rate_limit] enabled = false [server.features.auth] enabled = false [server.features.cache] enabled = false [server.features.multi_tenant] enabled = false " $config_content | save -f $config_file log info $"✓ Created main config: ($config_file)" # Create FEATURE configs (Tier 2) create_feature_config $features_dir "database" $"[database] migrations_path = \"./migrations\" auto_migrate = true connection_pool_size = 10 log_queries = false " create_feature_config $features_dir "health" $"[health] database_timeout_ms = 5000 include_version = true include_uptime = true include_database_status = true " create_feature_config $features_dir "metrics" $"[metrics] metrics_path = \"/metrics\" request_duration_buckets = [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000] trace_requests = false collect_performance_metrics = true track_memory = true " create_feature_config $features_dir "rate_limit" $"[rate_limit] requests_per_second = 10 burst_size = 20 rate_limit_health_metrics = false rate_limit_message = \"Too many requests\" " create_feature_config $features_dir "auth" $"[auth] api_keys = [] auth_header = \"Authorization\" auth_prefix = \"Bearer\" strict_validation = true log_failures = true " create_feature_config $features_dir "cache" $"[cache] backend = \"memory\" max_items = 10000 ttl_seconds = 3600 [cache.memory] eviction_enabled = true eviction_interval_seconds = 300 [cache.redis] connection_url = \"redis://localhost:6379/0\" connection_timeout_ms = 5000 key_prefix = \"syntaxis:\" " create_feature_config $features_dir "multi_tenant" $"[multi_tenant] tenant_id_source = \"header\" tenant_header_name = \"X-Tenant-ID\" require_tenant_id = false isolation_level = \"row\" allow_schema_customization = false max_tenants = 1000 include_tenant_in_logs = true " # Create wrapper script # Binary is resolved from PATH (installed via 'cargo install') let binary_name = ($binary | path basename) let wrapper_file = $"($install_dir)/($binary_name).sh" let marker = "# [GENERATED_BY_INSTALL_ALL_TARGETS]" let wrapper_content = $"#!/bin/bash # Lifecycle Server Wrapper $marker # Binary resolved from PATH (installed via 'cargo install') # Multi-file configuration: main config and feature configs export SYNTAXIS_DATA_DIR=\"($data_dir)\" export SYNTAXIS_CONFIG_DIR=\"($config_dir)\" export SYNTAXIS_FEATURES_DIR=\"($features_dir)\" exec \"$binary_name\" --config \"($config_file)\" \"\$@\" " # Check if wrapper already exists if ($wrapper_file | path exists) { let existing = open $wrapper_file # Only touch if we generated it (check for marker) if ($existing | str contains $marker) { if $existing == $wrapper_content { log info $"✓ Wrapper already up-to-date: ($wrapper_file)" } else { $wrapper_content | save -f $wrapper_file chmod +x $wrapper_file log info $"♻️ Updated wrapper: ($wrapper_file)" } } else { log warn $"⚠️ Wrapper already exists and appears customized (no marker found)" log warn $" To regenerate, move/remove: ($wrapper_file)" } } else { $wrapper_content | save -f $wrapper_file chmod +x $wrapper_file log info $"✓ Created wrapper: ($wrapper_file)" } } def create_feature_config [features_dir, feature_name, content] { let feature_file = $"($features_dir)/($feature_name).toml" $content | save -f $feature_file log info $" ✓ Feature config: ($feature_file)" } def install_tui [config_dir, install_dir, data_dir, project_root] { log info "📦 Installing syntaxis-tui..." let binary = $"($project_root)/target/release/syntaxis-tui" if not ($binary | path exists) { log warn $"Binary not found in: ($binary)" log info " Binary will be resolved from PATH (ensure 'cargo install' was run)" } let config_file = $"($config_dir)/syntaxis-tui.toml" # Create config file let config_content = $"# Lifecycle TUI Configuration [tui] theme = \"dark\" [database] path = \"($data_dir)/syntaxis.db\" [api] enabled = false base_url = \"http://localhost:3000\" auth_token = \"\" timeout_secs = 30 [ui] show_timestamps = true confirm_actions = true auto_refresh_ms = 5000 " $config_content | save -f $config_file log info $"✓ Created config: ($config_file)" # Create wrapper script # Binary is resolved from PATH (installed via 'cargo install') let binary_name = ($binary | path basename) let wrapper_file = $"($install_dir)/($binary_name).sh" let marker = "# [GENERATED_BY_INSTALL_ALL_TARGETS]" let wrapper_content = $"#!/bin/bash # Lifecycle TUI Wrapper $marker # Binary resolved from PATH (installed via 'cargo install') export SYNTAXIS_DATA_DIR=\"($data_dir)\" export SYNTAXIS_CONFIG_DIR=\"($config_dir)\" # Use local mode by default # For remote mode: syntaxis-tui --remote --api-url http://localhost:3000 exec \"$binary_name\" \"\$@\" " # Check if wrapper already exists if ($wrapper_file | path exists) { let existing = open $wrapper_file # Only touch if we generated it (check for marker) if ($existing | str contains $marker) { if $existing == $wrapper_content { log info $"✓ Wrapper already up-to-date: ($wrapper_file)" } else { $wrapper_content | save -f $wrapper_file chmod +x $wrapper_file log info $"♻️ Updated wrapper: ($wrapper_file)" } } else { log warn $"⚠️ Wrapper already exists and appears customized (no marker found)" log warn $" To regenerate, move/remove: ($wrapper_file)" } } else { $wrapper_content | save -f $wrapper_file chmod +x $wrapper_file log info $"✓ Created wrapper: ($wrapper_file)" } } def install_dashboard [config_dir, install_dir, data_dir, project_root] { log info "📦 Installing syntaxis-dashboard..." let binary = $"($project_root)/target/release/syntaxis-dashboard" if not ($binary | path exists) { log warn $"Binary not found in: ($binary)" log info " Binary will be resolved from PATH (ensure 'cargo install' was run)" } let config_file = $"($config_dir)/syntaxis-dashboard.toml" # Create config file let config_content = $"# Lifecycle Dashboard Configuration [server] host = \"0.0.0.0\" port = 5173 dev_server = true [api] url = \"http://localhost:3000\" timeout_secs = 30 retries = 3 [ui] theme = \"auto\" language = \"en\" [features] enable_realtime_updates = true enable_export = true enable_advanced_analytics = true " $config_content | save -f $config_file log info $"✓ Created config: ($config_file)" # Create wrapper script # Binary is resolved from PATH (installed via 'cargo install') let binary_name = ($binary | path basename) let wrapper_file = $"($install_dir)/($binary_name).sh" let marker = "# [GENERATED_BY_INSTALL_ALL_TARGETS]" let wrapper_content = $"#!/bin/bash # Lifecycle Dashboard Wrapper $marker # Binary resolved from PATH (installed via 'cargo install') export SYNTAXIS_DATA_DIR=\"($data_dir)\" export SYNTAXIS_CONFIG_DIR=\"($config_dir)\" export SYNTAXIS_API_URL=\"http://localhost:3000\" export SYNTAXIS_DASHBOARD_PORT=\"5173\" exec \"$binary_name\" \"\$@\" " # Check if wrapper already exists if ($wrapper_file | path exists) { let existing = open $wrapper_file # Only touch if we generated it (check for marker) if ($existing | str contains $marker) { if $existing == $wrapper_content { log info $"✓ Wrapper already up-to-date: ($wrapper_file)" } else { $wrapper_content | save -f $wrapper_file chmod +x $wrapper_file log info $"♻️ Updated wrapper: ($wrapper_file)" } } else { log warn $"⚠️ Wrapper already exists and appears customized (no marker found)" log warn $" To regenerate, move/remove: ($wrapper_file)" } } else { $wrapper_content | save -f $wrapper_file chmod +x $wrapper_file log info $"✓ Created wrapper: ($wrapper_file)" } }