{"repo": "barstoolbluz/agentic-development-with-flox", "files": {"crush/.flox/env/manifest.toml": {"3256a3dd5780462311c371345b6f66cb22773894": {"t": 1785745354.793257, "n": 21897, "h": "677a147b9a076a3e", "c": "## Flox Environment Manifest -----------------------------------------\n##\n## _Everything_ you need to know about the _manifest_ is here:\n##\n## https://flox.dev/docs/reference/command-reference/manifest.toml/\n##\n## -------------------------------------------------------------------\n# Flox manifest version managed by Flox CLI\nversion = 1\n\n\n## Install Packages --------------------------------------------------\n[install]\ncrush.pkg-path = \"flox/crush\"\ncrush.pkg-group = \"crush\"\ngum.pkg-path = \"gum\"\njq.pkg-path = \"jq\"\nopenssl.pkg-path = \"openssl\"\ncurl.pkg-path = \"curl\"\n\n# Flox MCP Server - enables Crush to manage Flox environments\nflox-mcp-server.pkg-path = \"flox/flox-mcp-server\"\nflox-mcp-server.systems = [\"aarch64-darwin\", \"aarch64-linux\", \"x86_64-linux\"]\n\n\n## Environment Variables ---------------------------------------------\n[vars]\n\n\n## Activation Hook ---------------------------------------------------\n[hook]\non-activate = '''\n# =============================================================================\n# Crush Setup Wizard - Comprehensive Configuration with Encrypted Secrets\n# =============================================================================\n\n# Configuration paths\nCONFIG_DIR=\"$HOME/.local/share/crush\"\nCONFIG_FILE=\"$CONFIG_DIR/crush.json\"\nCONFIG_BACKUP=\"$CONFIG_DIR/crush.json.backup\"\nSECRETS_DIR=\"$HOME/.config/crush/secrets\"\nSECRETS_CONFIG=\"$SECRETS_DIR/config\"\nSETUP_MARKER=\"$HOME/.config/crush/.flox_setup_done\"\nWIZARD_IN_PROGRESS=\"$HOME/.config/crush/.wizard_in_progress\"\n\nmkdir -p \"$CONFIG_DIR\" \"$SECRETS_DIR\" \"$(dirname \"$SETUP_MARKER\")\"\nchmod 700 \"$SECRETS_DIR\"\n\n# =============================================================================\n# OS Detection\n# =============================================================================\ndetect_os() {\n if [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n echo \"macos\"\n elif [[ \"$OSTYPE\" == \"linux-gnu\"* ]]; then\n echo \"linux\"\n else\n echo \"unsupported\"\n fi\n}\n\n# =============================================================================\n# Encryption Functions\n# =============================================================================\nget_machine_id() {\n if [[ -f \"/etc/machine-id\" ]]; then\n cat /etc/machine-id\n elif [[ -f \"/var/lib/dbus/machine-id\" ]]; then\n cat /var/lib/dbus/machine-id\n elif [[ \"$(detect_os)\" == \"macos\" ]]; then\n ioreg -rd1 -c IOPlatformExpertDevice | grep -E '(UUID)' | awk '{print $3}' | tr -d '\"'\n else\n echo \"fallback-$(hostname)\"\n fi\n}\n\nderive_password() {\n local salt=\"$1\"\n local machine_id=$(get_machine_id)\n echo -n \"${USER}$(hostname)${machine_id}${salt}\" | openssl dgst -sha256 | awk '{print $2}'\n}\n\n# Store API key - tries keyring first, falls back to encrypted file\nstore_api_key() {\n local provider=\"$1\"\n local api_key=\"$2\"\n local os=$(detect_os)\n local service_name=\"crush-${provider}\"\n\n # Try system keyring first\n if [[ \"$os\" == \"macos\" ]]; then\n if security add-generic-password -s \"$service_name\" -a \"$USER\" -w \"$api_key\" -U 2>/dev/null; then\n echo \"${provider}=keyring\" >> \"$SECRETS_CONFIG\"\n return 0\n fi\n elif [[ \"$os\" == \"linux\" ]] && command -v secret-tool >/dev/null 2>&1; then\n if echo -n \"$api_key\" | secret-tool store --label=\"Crush ${provider} API Key\" service \"$service_name\" user \"$USER\" 2>/dev/null; then\n echo \"${provider}=keyring\" >> \"$SECRETS_CONFIG\"\n return 0\n fi\n fi\n\n # Fallback to encrypted file\n local password=$(derive_password \"${provider}-api-key\")\n local enc_file=\"$SECRETS_DIR/${provider}.enc\"\n echo -n \"$api_key\" | openssl enc -aes-256-cbc -salt -pbkdf2 -pass pass:\"$password\" -out \"$enc_file\" 2>/dev/null\n chmod 600 \"$enc_file\"\n echo \"${provider}=encrypted_file\" >> \"$SECRETS_CONFIG\"\n return 0\n}\n\n# Retrieve API key from storage\nretrieve_api_key() {\n local provider=\"$1\"\n local os=$(detect_os)\n local service_name=\"crush-${provider}\"\n local method=\"\"\n\n [[ -f \"$SECRETS_CONFIG\" ]] && method=$(grep \"^${provider}=\" \"$SECRETS_CONFIG\" | cut -d= -f2)\n\n if [[ \"$method\" == \"keyring\" ]]; then\n if [[ \"$os\" == \"macos\" ]]; then\n security find-generic-password -s \"$service_name\" -a \"$USER\" -w 2>/dev/null\n elif [[ \"$os\" == \"linux\" ]]; then\n secret-tool lookup service \"$service_name\" user \"$USER\" 2>/dev/null\n fi\n elif [[ \"$method\" == \"encrypted_file\" ]]; then\n local password=$(derive_password \"${provider}-api-key\")\n local enc_file=\"$SECRETS_DIR/${provider}.enc\"\n [[ -f \"$enc_file\" ]] && openssl enc -aes-256-cbc -d -salt -pbkdf2 -pass pass:\"$password\" -in \"$enc_file\" 2>/dev/null\n fi\n}\n\n# Check if provider key exists\nhas_api_key() {\n local provider=\"$1\"\n [[ -f \"$SECRETS_CONFIG\" ]] && grep -q \"^${provider}=\" \"$SECRETS_CONFIG\"\n}\n\n# =============================================================================\n# UI Functions\n# =============================================================================\nshow_box() {\n local title=\"$1\"\n local content=\"$2\"\n gum style \\\n --border rounded \\\n --border-foreground 212 \\\n --padding \"1 2\" \\\n --margin \"1 0\" \\\n --width 80 \\\n \"$(gum style --foreground 141 --bold \"$title\")\n\n$content\"\n}\n\nshow_welcome() {\n show_box \"✨ Crush Setup Wizard\" \"Welcome to the Crush setup wizard!\n\nCrush is a glamorous AI coding agent for the terminal from Charm.\n\nThis wizard will help you configure:\n $(gum style --foreground 212 '•') LLM provider(s) with encrypted API key storage\n $(gum style --foreground 212 '•') Local Ollama models (optional)\n $(gum style --foreground 212 '•') Flox MCP Server integration (optional)\n\n$(gum style --foreground 240 'Configuration:') $CONFIG_FILE\n$(gum style --foreground 240 'Encrypted secrets:') $SECRETS_DIR\"\n}\n\n# =============================================================================\n# Config Backup/Rollback\n# =============================================================================\nbackup_config() {\n if [[ -f \"$CONFIG_FILE\" ]]; then\n cp \"$CONFIG_FILE\" \"$CONFIG_BACKUP\"\n fi\n}\n\nrollback_config() {\n if [[ -f \"$CONFIG_BACKUP\" ]]; then\n cp \"$CONFIG_BACKUP\" \"$CONFIG_FILE\"\n rm -f \"$WIZARD_IN_PROGRESS\"\n echo \"Configuration rolled back successfully.\"\n return 0\n fi\n echo \"No backup found.\"\n return 1\n}\n\n# =============================================================================\n# Provider Configuration Functions\n# =============================================================================\ncollect_api_key() {\n local provider=\"$1\"\n local prefix=\"$2\"\n local placeholder=\"$3\"\n\n while true; do\n local api_key=$(gum input \\\n --prompt \"Enter your $provider API key: \" \\\n --password \\\n --width 70 \\\n --placeholder \"$placeholder\")\n\n if [[ -z \"$api_key\" ]]; then\n if gum confirm \"Skip $provider configuration?\" --default=false; then\n return 1\n fi\n continue\n fi\n\n if [[ -n \"$prefix\" ]] && [[ ! \"$api_key\" =~ ^$prefix ]]; then\n if ! gum confirm \"Key does not start with '$prefix'. Use anyway?\" --default=false; then\n continue\n fi\n fi\n\n store_api_key \"$provider\" \"$api_key\"\n return 0\n done\n}\n\nconfigure_anthropic() {\n show_box \"Anthropic (Claude)\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://console.anthropic.com/settings/keys')\n\nAnthropic provides Claude models - powerful AI for coding and analysis.\"\n collect_api_key \"anthropic\" \"sk-ant-\" \"sk-ant-...\"\n}\n\nconfigure_openai() {\n show_box \"OpenAI (GPT)\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://platform.openai.com/api-keys')\n\nOpenAI provides GPT-4, GPT-4o, and other models.\"\n collect_api_key \"openai\" \"sk-\" \"sk-...\"\n}\n\nconfigure_gemini() {\n show_box \"Google Gemini\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://aistudio.google.com/apikey')\n\nGoogle Gemini provides advanced multimodal AI capabilities.\"\n collect_api_key \"gemini\" \"\" \"AI...\"\n}\n\nconfigure_groq() {\n show_box \"Groq\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://console.groq.com/keys')\n\nGroq provides ultra-fast inference for open models like Llama and Mixtral.\"\n collect_api_key \"groq\" \"gsk_\" \"gsk_...\"\n}\n\nconfigure_deepseek() {\n show_box \"DeepSeek\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://platform.deepseek.com/api_keys')\n\nDeepSeek provides powerful and cost-effective AI models.\"\n collect_api_key \"deepseek\" \"sk-\" \"sk-...\"\n}\n\nconfigure_ollama() {\n show_box \"Ollama (Local)\" \"Ollama runs AI models locally on your machine.\n\n $(gum style --foreground 212 '•') No API key required\n $(gum style --foreground 212 '•') Models run entirely on your hardware\n $(gum style --foreground 212 '•') Default endpoint: http://localhost:11434\"\n\n local endpoint=$(gum input \\\n --prompt \"Ollama endpoint URL: \" \\\n --value \"http://localhost:11434\" \\\n --width 70)\n\n [[ -z \"$endpoint\" ]] && endpoint=\"http://localhost:11434\"\n\n # Try to detect available models\n local models=\"\"\n local detected_models=$(curl -s --connect-timeout 2 \"${endpoint}/api/tags\" 2>/dev/null | jq -r '.models[].name' 2>/dev/null)\n\n if [[ -n \"$detected_models\" ]]; then\n show_box \"Detected Ollama Models\" \"Found running Ollama instance with these models:\n\n$(echo \"$detected_models\" | head -10 | sed 's/^/ • /')\n\nSelect which models to configure for Crush.\"\n\n local selected=$(echo \"$detected_models\" | gum choose --no-limit --header \"Select models (space to toggle, enter to confirm)\")\n models=\"$selected\"\n else\n echo \"Could not connect to Ollama at $endpoint\"\n if gum confirm \"Enter model name manually?\" --default=true; then\n models=$(gum input \\\n --prompt \"Model name: \" \\\n --value \"qwen3\" \\\n --placeholder \"qwen3, llama3.2, etc.\")\n fi\n fi\n\n if [[ -n \"$models\" ]]; then\n # Store Ollama config (endpoint + models as comma-separated)\n local models_csv=$(echo \"$models\" | tr '\\n' ',' | sed 's/,$//')\n echo \"ollama_endpoint=$endpoint\" >> \"$SECRETS_CONFIG\"\n echo \"ollama_models=$models_csv\" >> \"$SECRETS_CONFIG\"\n return 0\n fi\n return 1\n}\n\nconfigure_flox_mcp() {\n if ! command -v flox-mcp >/dev/null 2>&1; then\n return 1\n fi\n\n show_box \"Flox MCP Server Integration\" \"The Flox MCP Server enables Crush to manage Flox environments:\n\n $(gum style --foreground 212 '•') Initialize and manage Flox environments\n $(gum style --foreground 212 '•') Search and install packages from 150,000+ packages\n $(gum style --foreground 212 '•') Run commands in isolated environments\n $(gum style --foreground 212 '•') Query environment and system information\"\n\n gum confirm \"Enable Flox MCP Server integration?\" --default=true\n}\n\n# =============================================================================\n# Config Generation\n# =============================================================================\ngenerate_config() {\n local enable_mcp=\"$1\"\n local config=\"{}\"\n\n # Load existing config to preserve other settings\n if [[ -f \"$CONFIG_FILE\" ]]; then\n config=$(cat \"$CONFIG_FILE\")\n fi\n\n # API keys are NOT stored in config - Crush reads from environment variables:\n # ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, GROQ_API_KEY, DEEPSEEK_API_KEY\n # These are exported by export_provider_keys() on activation\n\n # Add Anthropic provider if configured (no api_key - read from env)\n if has_api_key \"anthropic\"; then\n config=$(echo \"$config\" | jq '.providers.anthropic = {\"type\": \"anthropic\"}')\n fi\n\n # Add OpenAI provider if configured (no api_key - read from env)\n if has_api_key \"openai\"; then\n config=$(echo \"$config\" | jq '.providers.openai = {\"type\": \"openai\"}')\n fi\n\n # Add Gemini provider if configured (needs base_url for OpenAI-compat)\n if has_api_key \"gemini\"; then\n config=$(echo \"$config\" | jq '.providers.gemini = {\n \"type\": \"openai-compat\",\n \"base_url\": \"https://generativelanguage.googleapis.com/v1beta/openai/\"\n }')\n fi\n\n # Add Groq provider if configured (needs base_url for OpenAI-compat)\n if has_api_key \"groq\"; then\n config=$(echo \"$config\" | jq '.providers.groq = {\n \"type\": \"openai-compat\",\n \"base_url\": \"https://api.groq.com/openai/v1\"\n }')\n fi\n\n # Add DeepSeek provider if configured (needs base_url for OpenAI-compat)\n if has_api_key \"deepseek\"; then\n config=$(echo \"$config\" | jq '.providers.deepseek = {\n \"type\": \"openai-compat\",\n \"base_url\": \"https://api.deepseek.com/v1\"\n }')\n fi\n\n # Add Ollama provider if configured (local, no API key needed)\n if grep -q \"^ollama_endpoint=\" \"$SECRETS_CONFIG\" 2>/dev/null; then\n local ollama_endpoint=$(grep \"^ollama_endpoint=\" \"$SECRETS_CONFIG\" | cut -d= -f2)\n local ollama_models=$(grep \"^ollama_models=\" \"$SECRETS_CONFIG\" | cut -d= -f2)\n\n # Build models array (models are comma-separated)\n local models_json=\"[]\"\n IFS=',' read -ra model_array <<< \"$ollama_models\"\n for model in \"${model_array[@]}\"; do\n [[ -z \"$model\" ]] && continue\n models_json=$(echo \"$models_json\" | jq --arg m \"$model\" '. + [{\"id\": $m, \"name\": $m, \"context_window\": 32000}]')\n done\n\n config=$(echo \"$config\" | jq --arg url \"${ollama_endpoint}/v1/\" --argjson models \"$models_json\" \\\n '.providers.ollama = {\"type\": \"openai-compat\", \"base_url\": $url, \"models\": $models}')\n fi\n\n # Add MCP configuration if enabled\n if [[ \"$enable_mcp\" == \"true\" ]]; then\n config=$(echo \"$config\" | jq '.mcp.flox = {\"type\": \"stdio\", \"command\": \"flox-mcp\"}')\n fi\n\n # Write config\n echo \"$config\" | jq '.' > \"$CONFIG_FILE\"\n chmod 600 \"$CONFIG_FILE\"\n}\n\n# =============================================================================\n# Export Environment Variables (for Crush to use)\n# =============================================================================\nexport_provider_keys() {\n for provider in anthropic openai gemini groq deepseek; do\n if has_api_key \"$provider\"; then\n local key=$(retrieve_api_key \"$provider\")\n if [[ -n \"$key\" ]]; then\n local var_name=$(echo \"${provider}_API_KEY\" | tr \"[:lower:]\" \"[:upper:]\")\n export \"$var_name=$key\"\n fi\n fi\n done\n}\n\n# =============================================================================\n# Main Wizard\n# =============================================================================\nrun_setup_wizard() {\n clear\n\n # Check for interrupted wizard\n if [[ -f \"$WIZARD_IN_PROGRESS\" ]]; then\n if gum confirm \"Previous setup was interrupted. Rollback to previous config?\" --default=true; then\n rollback_config\n rm -f \"$WIZARD_IN_PROGRESS\"\n fi\n fi\n\n # Check for existing config\n if [[ -f \"$CONFIG_FILE\" ]] && [[ -s \"$CONFIG_FILE\" ]]; then\n if ! gum confirm \"Existing configuration found. Overwrite?\" --default=false; then\n echo \"Setup cancelled. Keeping existing configuration.\"\n return 0\n fi\n fi\n\n # Backup and mark in progress\n backup_config\n touch \"$WIZARD_IN_PROGRESS\"\n\n # Clear previous secrets config\n > \"$SECRETS_CONFIG\"\n\n show_welcome\n\n echo \"\"\n\n # Multi-select providers\n local providers=$(gum choose --no-limit \\\n --header \"Select LLM providers to configure (space to toggle, enter to confirm)\" \\\n \"Anthropic (Claude)\" \\\n \"OpenAI (GPT)\" \\\n \"Google Gemini\" \\\n \"Groq\" \\\n \"DeepSeek\" \\\n \"Ollama (Local)\")\n\n local configured_providers=\"\"\n\n # Configure each selected provider (read line by line to handle spaces in names)\n while IFS= read -r provider; do\n [[ -z \"$provider\" ]] && continue\n case \"$provider\" in\n \"Anthropic (Claude)\")\n if configure_anthropic; then\n configured_providers=\"${configured_providers:+$configured_providers, }Anthropic\"\n fi\n ;;\n \"OpenAI (GPT)\")\n if configure_openai; then\n configured_providers=\"${configured_providers:+$configured_providers, }OpenAI\"\n fi\n ;;\n \"Google Gemini\")\n if configure_gemini; then\n configured_providers=\"${configured_providers:+$configured_providers, }Gemini\"\n fi\n ;;\n \"Groq\")\n if configure_groq; then\n configured_providers=\"${configured_providers:+$configured_providers, }Groq\"\n fi\n ;;\n \"DeepSeek\")\n if configure_deepseek; then\n configured_providers=\"${configured_providers:+$configured_providers, }DeepSeek\"\n fi\n ;;\n \"Ollama (Local)\")\n if configure_ollama; then\n configured_providers=\"${configured_providers:+$configured_providers, }Ollama\"\n fi\n ;;\n esac\n done <<< \"$providers\"\n\n # Flox MCP Server\n local enable_mcp=\"false\"\n if configure_flox_mcp; then\n enable_mcp=\"true\"\n fi\n\n # Generate configuration\n generate_config \"$enable_mcp\"\n\n # Mark complete\n rm -f \"$WIZARD_IN_PROGRESS\"\n touch \"$SETUP_MARKER\"\n\n # Show completion\n local mcp_status=\"Disabled\"\n [[ \"$enable_mcp\" == \"true\" ]] && mcp_status=\"$(gum style --foreground 42 'Enabled')\"\n\n show_box \"✨ Setup Complete!\" \"Crush has been configured successfully!\n\n$(gum style --foreground 212 'Providers:') ${configured_providers:-None configured}\n$(gum style --foreground 212 'Flox MCP:') $mcp_status\n$(gum style --foreground 212 'Config:') $CONFIG_FILE\n$(gum style --foreground 212 'Secrets:') Encrypted in $SECRETS_DIR\n\n$(gum style --foreground 240 'Helper commands:')\n crush_rollback - Restore previous configuration\n crush_reset - Re-run this setup wizard\n\n$(gum style --foreground 212 'Get started:') crush\"\n}\n\n# =============================================================================\n# Status Display\n# =============================================================================\nshow_status() {\n local providers=\"\"\n for p in anthropic openai gemini groq deepseek; do\n has_api_key \"$p\" && providers=\"${providers:+$providers, }$p\"\n done\n grep -q \"^ollama_endpoint=\" \"$SECRETS_CONFIG\" 2>/dev/null && providers=\"${providers:+$providers, }ollama\"\n\n local mcp_status=\"disabled\"\n [[ -f \"$CONFIG_FILE\" ]] && jq -e '.mcp.flox' \"$CONFIG_FILE\" >/dev/null 2>&1 && mcp_status=\"enabled\"\n\n gum style --foreground 212 \"✨ Crush ready\"\n echo \" providers=[${providers:-none}] mcp=$mcp_status\"\n echo \"\"\n gum style --foreground 240 \" RESET=true flox activate to reconfigure\"\n}\n\n# =============================================================================\n# Main Entry Point\n# =============================================================================\n\n# Export API keys as environment variables for Crush to use\nexport_provider_keys\n\n# Check wizard state\nif [[ \"$RESET\" == \"true\" ]]; then\n rm -f \"$SETUP_MARKER\" 2>/dev/null\n run_setup_wizard\nelif [[ -f \"$WIZARD_IN_PROGRESS\" ]]; then\n if gum confirm \"Previous setup was interrupted. Resume wizard?\" --default=true; then\n run_setup_wizard\n else\n rollback_config\n show_status\n fi\nelif [[ ! -f \"$SETUP_MARKER\" ]] || [[ ! -f \"$CONFIG_FILE\" ]]; then\n run_setup_wizard\nelse\n show_status\nfi\n'''\n\n\n## Profile script ----------------------------------------------------\n[profile]\nbash = '''\n# Crush configuration helper functions\n\ncrush_rollback() {\n local backup=\"$HOME/.local/share/crush/crush.json.backup\"\n local config=\"$HOME/.local/share/crush/crush.json\"\n if [[ -f \"$backup\" ]]; then\n cp \"$backup\" \"$config\"\n echo \"✓ Rolled back to previous configuration\"\n echo \" Restart Crush to use restored settings\"\n else\n echo \"✗ No backup found at $backup\"\n return 1\n fi\n}\n\ncrush_reset() {\n echo \"This will reset Crush configuration and re-run the setup wizard.\"\n read -p \"Continue? [y/N] \" -r\n [[ $REPLY =~ ^[Yy]$ ]] || return 1\n rm -f \"$HOME/.config/crush/.flox_setup_done\"\n echo \"Run 'flox activate' to restart the setup wizard\"\n}\n'''\n\nzsh = '''\n# Crush configuration helper functions\n\ncrush_rollback() {\n local backup=\"$HOME/.local/share/crush/crush.json.backup\"\n local config=\"$HOME/.local/share/crush/crush.json\"\n if [[ -f \"$backup\" ]]; then\n cp \"$backup\" \"$config\"\n echo \"✓ Rolled back to previous configuration\"\n echo \" Restart Crush to use restored settings\"\n else\n echo \"✗ No backup found at $backup\"\n return 1\n fi\n}\n\ncrush_reset() {\n echo \"This will reset Crush configuration and re-run the setup wizard.\"\n read -q \"?Continue? [y/N] \" || return 1\n echo\n rm -f \"$HOME/.config/crush/.flox_setup_done\"\n echo \"Run 'flox activate' to restart the setup wizard\"\n}\n'''\n\n\n## Services ----------------------------------------------------------\n[services]\n\n\n## Include -----------------------------------------------------------\n[include]\n\n\n## Build -------------------------------------------------------------\n[build]\n\n\n## Options -----------------------------------------------------------\n[options]\nsystems = [\n \"aarch64-darwin\",\n \"aarch64-linux\",\n \"x86_64-darwin\",\n \"x86_64-linux\",\n]\n"}, "181ee3f86e306a939af1977beff6ce55567d7d57": {"t": 1785750608.2206502, "n": 21897, "h": "677a147b9a076a3e", "c": "## Flox Environment Manifest -----------------------------------------\n##\n## _Everything_ you need to know about the _manifest_ is here:\n##\n## https://flox.dev/docs/reference/command-reference/manifest.toml/\n##\n## -------------------------------------------------------------------\n# Flox manifest version managed by Flox CLI\nversion = 1\n\n\n## Install Packages --------------------------------------------------\n[install]\ncrush.pkg-path = \"flox/crush\"\ncrush.pkg-group = \"crush\"\ngum.pkg-path = \"gum\"\njq.pkg-path = \"jq\"\nopenssl.pkg-path = \"openssl\"\ncurl.pkg-path = \"curl\"\n\n# Flox MCP Server - enables Crush to manage Flox environments\nflox-mcp-server.pkg-path = \"flox/flox-mcp-server\"\nflox-mcp-server.systems = [\"aarch64-darwin\", \"aarch64-linux\", \"x86_64-linux\"]\n\n\n## Environment Variables ---------------------------------------------\n[vars]\n\n\n## Activation Hook ---------------------------------------------------\n[hook]\non-activate = '''\n# =============================================================================\n# Crush Setup Wizard - Comprehensive Configuration with Encrypted Secrets\n# =============================================================================\n\n# Configuration paths\nCONFIG_DIR=\"$HOME/.local/share/crush\"\nCONFIG_FILE=\"$CONFIG_DIR/crush.json\"\nCONFIG_BACKUP=\"$CONFIG_DIR/crush.json.backup\"\nSECRETS_DIR=\"$HOME/.config/crush/secrets\"\nSECRETS_CONFIG=\"$SECRETS_DIR/config\"\nSETUP_MARKER=\"$HOME/.config/crush/.flox_setup_done\"\nWIZARD_IN_PROGRESS=\"$HOME/.config/crush/.wizard_in_progress\"\n\nmkdir -p \"$CONFIG_DIR\" \"$SECRETS_DIR\" \"$(dirname \"$SETUP_MARKER\")\"\nchmod 700 \"$SECRETS_DIR\"\n\n# =============================================================================\n# OS Detection\n# =============================================================================\ndetect_os() {\n if [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n echo \"macos\"\n elif [[ \"$OSTYPE\" == \"linux-gnu\"* ]]; then\n echo \"linux\"\n else\n echo \"unsupported\"\n fi\n}\n\n# =============================================================================\n# Encryption Functions\n# =============================================================================\nget_machine_id() {\n if [[ -f \"/etc/machine-id\" ]]; then\n cat /etc/machine-id\n elif [[ -f \"/var/lib/dbus/machine-id\" ]]; then\n cat /var/lib/dbus/machine-id\n elif [[ \"$(detect_os)\" == \"macos\" ]]; then\n ioreg -rd1 -c IOPlatformExpertDevice | grep -E '(UUID)' | awk '{print $3}' | tr -d '\"'\n else\n echo \"fallback-$(hostname)\"\n fi\n}\n\nderive_password() {\n local salt=\"$1\"\n local machine_id=$(get_machine_id)\n echo -n \"${USER}$(hostname)${machine_id}${salt}\" | openssl dgst -sha256 | awk '{print $2}'\n}\n\n# Store API key - tries keyring first, falls back to encrypted file\nstore_api_key() {\n local provider=\"$1\"\n local api_key=\"$2\"\n local os=$(detect_os)\n local service_name=\"crush-${provider}\"\n\n # Try system keyring first\n if [[ \"$os\" == \"macos\" ]]; then\n if security add-generic-password -s \"$service_name\" -a \"$USER\" -w \"$api_key\" -U 2>/dev/null; then\n echo \"${provider}=keyring\" >> \"$SECRETS_CONFIG\"\n return 0\n fi\n elif [[ \"$os\" == \"linux\" ]] && command -v secret-tool >/dev/null 2>&1; then\n if echo -n \"$api_key\" | secret-tool store --label=\"Crush ${provider} API Key\" service \"$service_name\" user \"$USER\" 2>/dev/null; then\n echo \"${provider}=keyring\" >> \"$SECRETS_CONFIG\"\n return 0\n fi\n fi\n\n # Fallback to encrypted file\n local password=$(derive_password \"${provider}-api-key\")\n local enc_file=\"$SECRETS_DIR/${provider}.enc\"\n echo -n \"$api_key\" | openssl enc -aes-256-cbc -salt -pbkdf2 -pass pass:\"$password\" -out \"$enc_file\" 2>/dev/null\n chmod 600 \"$enc_file\"\n echo \"${provider}=encrypted_file\" >> \"$SECRETS_CONFIG\"\n return 0\n}\n\n# Retrieve API key from storage\nretrieve_api_key() {\n local provider=\"$1\"\n local os=$(detect_os)\n local service_name=\"crush-${provider}\"\n local method=\"\"\n\n [[ -f \"$SECRETS_CONFIG\" ]] && method=$(grep \"^${provider}=\" \"$SECRETS_CONFIG\" | cut -d= -f2)\n\n if [[ \"$method\" == \"keyring\" ]]; then\n if [[ \"$os\" == \"macos\" ]]; then\n security find-generic-password -s \"$service_name\" -a \"$USER\" -w 2>/dev/null\n elif [[ \"$os\" == \"linux\" ]]; then\n secret-tool lookup service \"$service_name\" user \"$USER\" 2>/dev/null\n fi\n elif [[ \"$method\" == \"encrypted_file\" ]]; then\n local password=$(derive_password \"${provider}-api-key\")\n local enc_file=\"$SECRETS_DIR/${provider}.enc\"\n [[ -f \"$enc_file\" ]] && openssl enc -aes-256-cbc -d -salt -pbkdf2 -pass pass:\"$password\" -in \"$enc_file\" 2>/dev/null\n fi\n}\n\n# Check if provider key exists\nhas_api_key() {\n local provider=\"$1\"\n [[ -f \"$SECRETS_CONFIG\" ]] && grep -q \"^${provider}=\" \"$SECRETS_CONFIG\"\n}\n\n# =============================================================================\n# UI Functions\n# =============================================================================\nshow_box() {\n local title=\"$1\"\n local content=\"$2\"\n gum style \\\n --border rounded \\\n --border-foreground 212 \\\n --padding \"1 2\" \\\n --margin \"1 0\" \\\n --width 80 \\\n \"$(gum style --foreground 141 --bold \"$title\")\n\n$content\"\n}\n\nshow_welcome() {\n show_box \"✨ Crush Setup Wizard\" \"Welcome to the Crush setup wizard!\n\nCrush is a glamorous AI coding agent for the terminal from Charm.\n\nThis wizard will help you configure:\n $(gum style --foreground 212 '•') LLM provider(s) with encrypted API key storage\n $(gum style --foreground 212 '•') Local Ollama models (optional)\n $(gum style --foreground 212 '•') Flox MCP Server integration (optional)\n\n$(gum style --foreground 240 'Configuration:') $CONFIG_FILE\n$(gum style --foreground 240 'Encrypted secrets:') $SECRETS_DIR\"\n}\n\n# =============================================================================\n# Config Backup/Rollback\n# =============================================================================\nbackup_config() {\n if [[ -f \"$CONFIG_FILE\" ]]; then\n cp \"$CONFIG_FILE\" \"$CONFIG_BACKUP\"\n fi\n}\n\nrollback_config() {\n if [[ -f \"$CONFIG_BACKUP\" ]]; then\n cp \"$CONFIG_BACKUP\" \"$CONFIG_FILE\"\n rm -f \"$WIZARD_IN_PROGRESS\"\n echo \"Configuration rolled back successfully.\"\n return 0\n fi\n echo \"No backup found.\"\n return 1\n}\n\n# =============================================================================\n# Provider Configuration Functions\n# =============================================================================\ncollect_api_key() {\n local provider=\"$1\"\n local prefix=\"$2\"\n local placeholder=\"$3\"\n\n while true; do\n local api_key=$(gum input \\\n --prompt \"Enter your $provider API key: \" \\\n --password \\\n --width 70 \\\n --placeholder \"$placeholder\")\n\n if [[ -z \"$api_key\" ]]; then\n if gum confirm \"Skip $provider configuration?\" --default=false; then\n return 1\n fi\n continue\n fi\n\n if [[ -n \"$prefix\" ]] && [[ ! \"$api_key\" =~ ^$prefix ]]; then\n if ! gum confirm \"Key does not start with '$prefix'. Use anyway?\" --default=false; then\n continue\n fi\n fi\n\n store_api_key \"$provider\" \"$api_key\"\n return 0\n done\n}\n\nconfigure_anthropic() {\n show_box \"Anthropic (Claude)\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://console.anthropic.com/settings/keys')\n\nAnthropic provides Claude models - powerful AI for coding and analysis.\"\n collect_api_key \"anthropic\" \"sk-ant-\" \"sk-ant-...\"\n}\n\nconfigure_openai() {\n show_box \"OpenAI (GPT)\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://platform.openai.com/api-keys')\n\nOpenAI provides GPT-4, GPT-4o, and other models.\"\n collect_api_key \"openai\" \"sk-\" \"sk-...\"\n}\n\nconfigure_gemini() {\n show_box \"Google Gemini\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://aistudio.google.com/apikey')\n\nGoogle Gemini provides advanced multimodal AI capabilities.\"\n collect_api_key \"gemini\" \"\" \"AI...\"\n}\n\nconfigure_groq() {\n show_box \"Groq\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://console.groq.com/keys')\n\nGroq provides ultra-fast inference for open models like Llama and Mixtral.\"\n collect_api_key \"groq\" \"gsk_\" \"gsk_...\"\n}\n\nconfigure_deepseek() {\n show_box \"DeepSeek\" \"Get your API key from:\n $(gum style --foreground 212 --underline 'https://platform.deepseek.com/api_keys')\n\nDeepSeek provides powerful and cost-effective AI models.\"\n collect_api_key \"deepseek\" \"sk-\" \"sk-...\"\n}\n\nconfigure_ollama() {\n show_box \"Ollama (Local)\" \"Ollama runs AI models locally on your machine.\n\n $(gum style --foreground 212 '•') No API key required\n $(gum style --foreground 212 '•') Models run entirely on your hardware\n $(gum style --foreground 212 '•') Default endpoint: http://localhost:11434\"\n\n local endpoint=$(gum input \\\n --prompt \"Ollama endpoint URL: \" \\\n --value \"http://localhost:11434\" \\\n --width 70)\n\n [[ -z \"$endpoint\" ]] && endpoint=\"http://localhost:11434\"\n\n # Try to detect available models\n local models=\"\"\n local detected_models=$(curl -s --connect-timeout 2 \"${endpoint}/api/tags\" 2>/dev/null | jq -r '.models[].name' 2>/dev/null)\n\n if [[ -n \"$detected_models\" ]]; then\n show_box \"Detected Ollama Models\" \"Found running Ollama instance with these models:\n\n$(echo \"$detected_models\" | head -10 | sed 's/^/ • /')\n\nSelect which models to configure for Crush.\"\n\n local selected=$(echo \"$detected_models\" | gum choose --no-limit --header \"Select models (space to toggle, enter to confirm)\")\n models=\"$selected\"\n else\n echo \"Could not connect to Ollama at $endpoint\"\n if gum confirm \"Enter model name manually?\" --default=true; then\n models=$(gum input \\\n --prompt \"Model name: \" \\\n --value \"qwen3\" \\\n --placeholder \"qwen3, llama3.2, etc.\")\n fi\n fi\n\n if [[ -n \"$models\" ]]; then\n # Store Ollama config (endpoint + models as comma-separated)\n local models_csv=$(echo \"$models\" | tr '\\n' ',' | sed 's/,$//')\n echo \"ollama_endpoint=$endpoint\" >> \"$SECRETS_CONFIG\"\n echo \"ollama_models=$models_csv\" >> \"$SECRETS_CONFIG\"\n return 0\n fi\n return 1\n}\n\nconfigure_flox_mcp() {\n if ! command -v flox-mcp >/dev/null 2>&1; then\n return 1\n fi\n\n show_box \"Flox MCP Server Integration\" \"The Flox MCP Server enables Crush to manage Flox environments:\n\n $(gum style --foreground 212 '•') Initialize and manage Flox environments\n $(gum style --foreground 212 '•') Search and install packages from 150,000+ packages\n $(gum style --foreground 212 '•') Run commands in isolated environments\n $(gum style --foreground 212 '•') Query environment and system information\"\n\n gum confirm \"Enable Flox MCP Server integration?\" --default=true\n}\n\n# =============================================================================\n# Config Generation\n# =============================================================================\ngenerate_config() {\n local enable_mcp=\"$1\"\n local config=\"{}\"\n\n # Load existing config to preserve other settings\n if [[ -f \"$CONFIG_FILE\" ]]; then\n config=$(cat \"$CONFIG_FILE\")\n fi\n\n # API keys are NOT stored in config - Crush reads from environment variables:\n # ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, GROQ_API_KEY, DEEPSEEK_API_KEY\n # These are exported by export_provider_keys() on activation\n\n # Add Anthropic provider if configured (no api_key - read from env)\n if has_api_key \"anthropic\"; then\n config=$(echo \"$config\" | jq '.providers.anthropic = {\"type\": \"anthropic\"}')\n fi\n\n # Add OpenAI provider if configured (no api_key - read from env)\n if has_api_key \"openai\"; then\n config=$(echo \"$config\" | jq '.providers.openai = {\"type\": \"openai\"}')\n fi\n\n # Add Gemini provider if configured (needs base_url for OpenAI-compat)\n if has_api_key \"gemini\"; then\n config=$(echo \"$config\" | jq '.providers.gemini = {\n \"type\": \"openai-compat\",\n \"base_url\": \"https://generativelanguage.googleapis.com/v1beta/openai/\"\n }')\n fi\n\n # Add Groq provider if configured (needs base_url for OpenAI-compat)\n if has_api_key \"groq\"; then\n config=$(echo \"$config\" | jq '.providers.groq = {\n \"type\": \"openai-compat\",\n \"base_url\": \"https://api.groq.com/openai/v1\"\n }')\n fi\n\n # Add DeepSeek provider if configured (needs base_url for OpenAI-compat)\n if has_api_key \"deepseek\"; then\n config=$(echo \"$config\" | jq '.providers.deepseek = {\n \"type\": \"openai-compat\",\n \"base_url\": \"https://api.deepseek.com/v1\"\n }')\n fi\n\n # Add Ollama provider if configured (local, no API key needed)\n if grep -q \"^ollama_endpoint=\" \"$SECRETS_CONFIG\" 2>/dev/null; then\n local ollama_endpoint=$(grep \"^ollama_endpoint=\" \"$SECRETS_CONFIG\" | cut -d= -f2)\n local ollama_models=$(grep \"^ollama_models=\" \"$SECRETS_CONFIG\" | cut -d= -f2)\n\n # Build models array (models are comma-separated)\n local models_json=\"[]\"\n IFS=',' read -ra model_array <<< \"$ollama_models\"\n for model in \"${model_array[@]}\"; do\n [[ -z \"$model\" ]] && continue\n models_json=$(echo \"$models_json\" | jq --arg m \"$model\" '. + [{\"id\": $m, \"name\": $m, \"context_window\": 32000}]')\n done\n\n config=$(echo \"$config\" | jq --arg url \"${ollama_endpoint}/v1/\" --argjson models \"$models_json\" \\\n '.providers.ollama = {\"type\": \"openai-compat\", \"base_url\": $url, \"models\": $models}')\n fi\n\n # Add MCP configuration if enabled\n if [[ \"$enable_mcp\" == \"true\" ]]; then\n config=$(echo \"$config\" | jq '.mcp.flox = {\"type\": \"stdio\", \"command\": \"flox-mcp\"}')\n fi\n\n # Write config\n echo \"$config\" | jq '.' > \"$CONFIG_FILE\"\n chmod 600 \"$CONFIG_FILE\"\n}\n\n# =============================================================================\n# Export Environment Variables (for Crush to use)\n# =============================================================================\nexport_provider_keys() {\n for provider in anthropic openai gemini groq deepseek; do\n if has_api_key \"$provider\"; then\n local key=$(retrieve_api_key \"$provider\")\n if [[ -n \"$key\" ]]; then\n local var_name=$(echo \"${provider}_API_KEY\" | tr \"[:lower:]\" \"[:upper:]\")\n export \"$var_name=$key\"\n fi\n fi\n done\n}\n\n# =============================================================================\n# Main Wizard\n# =============================================================================\nrun_setup_wizard() {\n clear\n\n # Check for interrupted wizard\n if [[ -f \"$WIZARD_IN_PROGRESS\" ]]; then\n if gum confirm \"Previous setup was interrupted. Rollback to previous config?\" --default=true; then\n rollback_config\n rm -f \"$WIZARD_IN_PROGRESS\"\n fi\n fi\n\n # Check for existing config\n if [[ -f \"$CONFIG_FILE\" ]] && [[ -s \"$CONFIG_FILE\" ]]; then\n if ! gum confirm \"Existing configuration found. Overwrite?\" --default=false; then\n echo \"Setup cancelled. Keeping existing configuration.\"\n return 0\n fi\n fi\n\n # Backup and mark in progress\n backup_config\n touch \"$WIZARD_IN_PROGRESS\"\n\n # Clear previous secrets config\n > \"$SECRETS_CONFIG\"\n\n show_welcome\n\n echo \"\"\n\n # Multi-select providers\n local providers=$(gum choose --no-limit \\\n --header \"Select LLM providers to configure (space to toggle, enter to confirm)\" \\\n \"Anthropic (Claude)\" \\\n \"OpenAI (GPT)\" \\\n \"Google Gemini\" \\\n \"Groq\" \\\n \"DeepSeek\" \\\n \"Ollama (Local)\")\n\n local configured_providers=\"\"\n\n # Configure each selected provider (read line by line to handle spaces in names)\n while IFS= read -r provider; do\n [[ -z \"$provider\" ]] && continue\n case \"$provider\" in\n \"Anthropic (Claude)\")\n if configure_anthropic; then\n configured_providers=\"${configured_providers:+$configured_providers, }Anthropic\"\n fi\n ;;\n \"OpenAI (GPT)\")\n if configure_openai; then\n configured_providers=\"${configured_providers:+$configured_providers, }OpenAI\"\n fi\n ;;\n \"Google Gemini\")\n if configure_gemini; then\n configured_providers=\"${configured_providers:+$configured_providers, }Gemini\"\n fi\n ;;\n \"Groq\")\n if configure_groq; then\n configured_providers=\"${configured_providers:+$configured_providers, }Groq\"\n fi\n ;;\n \"DeepSeek\")\n if configure_deepseek; then\n configured_providers=\"${configured_providers:+$configured_providers, }DeepSeek\"\n fi\n ;;\n \"Ollama (Local)\")\n if configure_ollama; then\n configured_providers=\"${configured_providers:+$configured_providers, }Ollama\"\n fi\n ;;\n esac\n done <<< \"$providers\"\n\n # Flox MCP Server\n local enable_mcp=\"false\"\n if configure_flox_mcp; then\n enable_mcp=\"true\"\n fi\n\n # Generate configuration\n generate_config \"$enable_mcp\"\n\n # Mark complete\n rm -f \"$WIZARD_IN_PROGRESS\"\n touch \"$SETUP_MARKER\"\n\n # Show completion\n local mcp_status=\"Disabled\"\n [[ \"$enable_mcp\" == \"true\" ]] && mcp_status=\"$(gum style --foreground 42 'Enabled')\"\n\n show_box \"✨ Setup Complete!\" \"Crush has been configured successfully!\n\n$(gum style --foreground 212 'Providers:') ${configured_providers:-None configured}\n$(gum style --foreground 212 'Flox MCP:') $mcp_status\n$(gum style --foreground 212 'Config:') $CONFIG_FILE\n$(gum style --foreground 212 'Secrets:') Encrypted in $SECRETS_DIR\n\n$(gum style --foreground 240 'Helper commands:')\n crush_rollback - Restore previous configuration\n crush_reset - Re-run this setup wizard\n\n$(gum style --foreground 212 'Get started:') crush\"\n}\n\n# =============================================================================\n# Status Display\n# =============================================================================\nshow_status() {\n local providers=\"\"\n for p in anthropic openai gemini groq deepseek; do\n has_api_key \"$p\" && providers=\"${providers:+$providers, }$p\"\n done\n grep -q \"^ollama_endpoint=\" \"$SECRETS_CONFIG\" 2>/dev/null && providers=\"${providers:+$providers, }ollama\"\n\n local mcp_status=\"disabled\"\n [[ -f \"$CONFIG_FILE\" ]] && jq -e '.mcp.flox' \"$CONFIG_FILE\" >/dev/null 2>&1 && mcp_status=\"enabled\"\n\n gum style --foreground 212 \"✨ Crush ready\"\n echo \" providers=[${providers:-none}] mcp=$mcp_status\"\n echo \"\"\n gum style --foreground 240 \" RESET=true flox activate to reconfigure\"\n}\n\n# =============================================================================\n# Main Entry Point\n# =============================================================================\n\n# Export API keys as environment variables for Crush to use\nexport_provider_keys\n\n# Check wizard state\nif [[ \"$RESET\" == \"true\" ]]; then\n rm -f \"$SETUP_MARKER\" 2>/dev/null\n run_setup_wizard\nelif [[ -f \"$WIZARD_IN_PROGRESS\" ]]; then\n if gum confirm \"Previous setup was interrupted. Resume wizard?\" --default=true; then\n run_setup_wizard\n else\n rollback_config\n show_status\n fi\nelif [[ ! -f \"$SETUP_MARKER\" ]] || [[ ! -f \"$CONFIG_FILE\" ]]; then\n run_setup_wizard\nelse\n show_status\nfi\n'''\n\n\n## Profile script ----------------------------------------------------\n[profile]\nbash = '''\n# Crush configuration helper functions\n\ncrush_rollback() {\n local backup=\"$HOME/.local/share/crush/crush.json.backup\"\n local config=\"$HOME/.local/share/crush/crush.json\"\n if [[ -f \"$backup\" ]]; then\n cp \"$backup\" \"$config\"\n echo \"✓ Rolled back to previous configuration\"\n echo \" Restart Crush to use restored settings\"\n else\n echo \"✗ No backup found at $backup\"\n return 1\n fi\n}\n\ncrush_reset() {\n echo \"This will reset Crush configuration and re-run the setup wizard.\"\n read -p \"Continue? [y/N] \" -r\n [[ $REPLY =~ ^[Yy]$ ]] || return 1\n rm -f \"$HOME/.config/crush/.flox_setup_done\"\n echo \"Run 'flox activate' to restart the setup wizard\"\n}\n'''\n\nzsh = '''\n# Crush configuration helper functions\n\ncrush_rollback() {\n local backup=\"$HOME/.local/share/crush/crush.json.backup\"\n local config=\"$HOME/.local/share/crush/crush.json\"\n if [[ -f \"$backup\" ]]; then\n cp \"$backup\" \"$config\"\n echo \"✓ Rolled back to previous configuration\"\n echo \" Restart Crush to use restored settings\"\n else\n echo \"✗ No backup found at $backup\"\n return 1\n fi\n}\n\ncrush_reset() {\n echo \"This will reset Crush configuration and re-run the setup wizard.\"\n read -q \"?Continue? [y/N] \" || return 1\n echo\n rm -f \"$HOME/.config/crush/.flox_setup_done\"\n echo \"Run 'flox activate' to restart the setup wizard\"\n}\n'''\n\n\n## Services ----------------------------------------------------------\n[services]\n\n\n## Include -----------------------------------------------------------\n[include]\n\n\n## Build -------------------------------------------------------------\n[build]\n\n\n## Options -----------------------------------------------------------\n[options]\nsystems = [\n \"aarch64-darwin\",\n \"aarch64-linux\",\n \"x86_64-darwin\",\n \"x86_64-linux\",\n]\n"}, "d541752471309b571483acd77f4992049fedc6fc": {"t": 1785750609.3136606, "n": 3416, "h": "5e137ea514439a57", "c": "## Flox Environment Manifest -----------------------------------------\n##\n## _Everything_ you need to know about the _manifest_ is here:\n##\n## https://flox.dev/docs/reference/command-reference/manifest.toml/\n##\n## -------------------------------------------------------------------\n# Flox manifest version managed by Flox CLI\nversion = 1\n\n\n## Install Packages --------------------------------------------------\n## $ flox install gum <- puts a package in [install] section below\n## $ flox search gum <- search for a package\n## $ flox show gum <- show all versions of a package\n## -------------------------------------------------------------------\n[install]\ncrush.pkg-path = \"crush\"\n# gum.pkg-path = \"gum\"\n# gum.version = \"^0.14.5\"\n\n\n## Environment Variables ---------------------------------------------\n## ... available for use in the activated environment\n## as well as [hook], [profile] scripts and [services] below.\n## -------------------------------------------------------------------\n[vars]\n# INTRO_MESSAGE = \"It's gettin' Flox in here\"\n\n\n## Activation Hook ---------------------------------------------------\n[hook]\non-activate = '''\necho \"\"\necho \"✨ Crush - AI Coding Agent for the Terminal\"\necho \"\"\necho \"Your glamorous AI coding bestie from Charm.\"\necho \"\"\necho \"First-time setup:\"\necho \" crush # Launch interactive session\"\necho \" # Configure API keys on first run\"\necho \"\"\necho \"Usage:\"\necho \" crush # Start conversational coding agent\"\necho \" crush --help # Show all options\"\necho \"\"\necho \"Features:\"\necho \" • Multi-model LLM support (OpenAI, Anthropic, custom APIs)\"\necho \" • Session-based organization per project\"\necho \" • LSP integration for code understanding\"\necho \" • MCP server extensibility\"\necho \" • Switch models mid-session without losing context\"\necho \" • Permission-based tool execution\"\necho \"\"\n'''\n\n\n## Profile script ----------------------------------------------------\n[profile]\n# No helper functions needed - crush is self-contained\n\n\n## Services ---------------------------------------------------------\n## $ flox services start <- Starts all services\n## $ flox services status <- Status of running services\n## $ flox activate --start-services <- Activates & starts all\n## ------------------------------------------------------------------\n[services]\n# myservice.command = \"python3 -m http.server\"\n\n\n## Include ----------------------------------------------------------\n## ... environments to create a composed environment\n## ------------------------------------------------------------------\n[include]\n# environments = [\n# { dir = \"../common\" }\n# ]\n\n\n## Build and publish your own packages ------------------------------\n## $ flox build\n## $ flox publish\n## ------------------------------------------------------------------\n[build]\n# [build.myproject]\n# description = \"The coolest project ever\"\n# version = \"0.0.1\"\n# command = \"\"\"\n# mkdir -p $out/bin\n# cargo build --release\n# cp target/release/myproject $out/bin/myproject\n# \"\"\"\n\n\n## Other Environment Options -----------------------------------------\n[options]\n# Systems that environment is compatible with\n# systems = [\n# \"aarch64-darwin\",\n# \"aarch64-linux\",\n# \"x86_64-darwin\",\n# \"x86_64-linux\",\n# ]\n# Uncomment to disable CUDA detection.\n# cuda-detection = false\n"}}, "claude-code-router/.flox/env/manifest.toml": {"3256a3dd5780462311c371345b6f66cb22773894": {"t": 1785745380.0300782, "n": 22690, "h": "4b025da1f6a5cd58", "c": "## Flox Environment Manifest -----------------------------------------\n##\n## _Everything_ you need to know about the _manifest_ is here:\n##\n## https://flox.dev/docs/concepts/manifest\n##\n## -------------------------------------------------------------------\n# Flox manifest version managed by Flox CLI\nversion = 1\n\n\n## Included: Local Ollama Service -----------------------------------\n## This environment includes local Ollama LLM support by default via\n## composition with the ollama-headless environment. This allows routing\n## requests to local models for privacy, offline use, and cost savings.\n##\n## To use Ollama:\n## 1. Add Ollama provider to ~/.claude-code-router/config.json:\n## {\n## \"name\": \"ollama\",\n## \"api_base_url\": \"http://localhost:11434/v1/chat/completions\",\n## \"api_key\": \"\",\n## \"models\": [\"qwen2.5-coder:32b\", \"deepseek-r1:32b\", ...]\n## }\n## 2. Start with: flox activate -s (starts both Ollama and router)\n##\n## To run WITHOUT Ollama (cloud providers only):\n## Option A: Comment out the [include] section below\n## Option B: Use 'flox activate' then 'flox services start ccr'\n## (this starts only the router service, not Ollama)\n##\n[include]\nollama = \"barstoolbluz/ollama-headless\"\n\n\n## Install Packages --------------------------------------------------\n[install]\nclaude-code-router.pkg-path = \"claude-code-router\"\nclaude-code.pkg-path = \"claude-code\"\ngum.pkg-path = \"gum\"\ncurl.pkg-path = \"curl\"\njq.pkg-path = \"jq\"\nbat.pkg-path = \"bat\"\n\n\n## Environment Variables ---------------------------------------------\n[vars]\n# Base configuration paths\nCCR_CONFIG_DIR = \"$HOME/.claude-code-router\"\nCCR_LOG_DIR = \"$HOME/.claude-code-router/logs\"\nCCR_CONFIG_FILE = \"$HOME/.claude-code-router/config.json\"\n\n# Runtime-configurable with defaults (headless pattern)\nCCR_HOST = \"${CCR_HOST:-127.0.0.1}\"\nCCR_PORT = \"${CCR_PORT:-3456}\"\nCCR_APIKEY = \"${CCR_APIKEY:-}\"\nCCR_PROXY_URL = \"${CCR_PROXY_URL:-}\"\nCCR_LOG_ENABLED = \"${CCR_LOG_ENABLED:-true}\"\nCCR_LOG_LEVEL = \"${CCR_LOG_LEVEL:-debug}\"\nCCR_API_TIMEOUT_MS = \"${CCR_API_TIMEOUT_MS:-600000}\"\nCCR_NON_INTERACTIVE = \"${CCR_NON_INTERACTIVE:-false}\"\n\n# API Keys (env var injection pattern)\nOPENAI_API_KEY = \"${OPENAI_API_KEY:-}\"\nDEEPSEEK_API_KEY = \"${DEEPSEEK_API_KEY:-}\"\nOPENROUTER_API_KEY = \"${OPENROUTER_API_KEY:-}\"\nGEMINI_API_KEY = \"${GEMINI_API_KEY:-}\"\nANTHROPIC_API_KEY = \"${ANTHROPIC_API_KEY:-}\"\n\n\n## Activation Hook ---------------------------------------------------\n[hook]\non-activate = '''\n# Create required directories\nmkdir -p \"$CCR_CONFIG_DIR\"\nmkdir -p \"$CCR_LOG_DIR\"\nmkdir -p \"$CCR_CONFIG_DIR/plugins\"\n\n# Function to check if config exists\ncheck_ccr_config() {\n [[ -f \"$CCR_CONFIG_FILE\" ]] || return 1\n [[ -s \"$CCR_CONFIG_FILE\" ]] || return 1\n return 0\n}\n\n# Display info\nshow_ccr_info() {\n local config_status\n if check_ccr_config; then\n config_status=\"✓ Configured\"\n else\n config_status=\"⚠️ Not configured\"\n fi\n\n echo \"\"\n echo \"✅ Claude Code Router environment ready (headless mode)\"\n echo \"\"\n echo \"Configuration:\"\n echo \" Config: $CCR_CONFIG_FILE ($config_status)\"\n echo \" Host: $CCR_HOST\"\n echo \" Port: $CCR_PORT\"\n echo \" Logs: $CCR_LOG_DIR\"\n echo \"\"\n echo \"Service Management:\"\n echo \" flox activate -s Start router service\"\n echo \" flox services status Check service status\"\n echo \" flox services logs ccr View service logs\"\n echo \"\"\n echo \"Configuration:\"\n echo \" ccr-setup Interactive config wizard\"\n echo \" ccr-config-example Generate example config\"\n echo \" ccr ui Open web UI for config\"\n echo \" ccr model Interactive model selector\"\n echo \"\"\n echo \"Runtime Customization (via env vars):\"\n echo \" CCR_HOST=0.0.0.0 CCR_APIKEY=secret flox activate -s\"\n echo \"\"\n echo \"Configure Claude Code:\"\n echo \" Set API base URL to: http://$CCR_HOST:$CCR_PORT\"\n echo \" ccr ui Open config UI in browser\"\n echo \"\"\n}\n\n# Main initialization\nif ! check_ccr_config; then\n echo \"ℹ️ No configuration found. Run 'ccr-setup' to create one.\"\nfi\n\nshow_ccr_info\n'''\n\n\n## Profile script ----------------------------------------------------\n[profile]\nbash = '''\n# Helper: Generate example configuration\nccr-config-example() {\n local config_file=\"${1:-$CCR_CONFIG_FILE}\"\n\n cat > \"$config_file\" << 'EOF'\n{\n \"LOG\": true,\n \"LOG_LEVEL\": \"debug\",\n \"API_TIMEOUT_MS\": 600000,\n \"NON_INTERACTIVE_MODE\": false,\n \"APIKEY\": \"\",\n \"HOST\": \"127.0.0.1\",\n \"PROXY_URL\": \"\",\n \"Providers\": [\n {\n \"name\": \"openrouter\",\n \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n \"api_key\": \"$OPENROUTER_API_KEY\",\n \"models\": [\n \"anthropic/claude-sonnet-4\",\n \"anthropic/claude-3.5-sonnet\",\n \"google/gemini-2.5-pro-preview\"\n ],\n \"transformer\": {\n \"use\": [\"openrouter\"]\n }\n },\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"$DEEPSEEK_API_KEY\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": {\n \"use\": [\"deepseek\"],\n \"deepseek-chat\": {\n \"use\": [\"tooluse\"]\n }\n }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"background\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\",\n \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n \"longContextThreshold\": 60000\n }\n}\nEOF\n\n echo \"✓ Example configuration created: $config_file\"\n echo \"\"\n echo \"Edit with: ${EDITOR:-nano} $config_file\"\n echo \"Or use: ccr-setup (interactive wizard)\"\n}\n\n# Helper: Interactive configuration wizard\nccr-setup() {\n if ! command -v gum &> /dev/null; then\n echo \"⚠️ gum not found. Using non-interactive mode.\"\n ccr-config-example\n return 0\n fi\n\n clear\n\n gum style \\\n --border rounded \\\n --border-foreground 240 \\\n --padding \"1 2\" \\\n --margin \"1 0\" \\\n --width 70 \\\n \"$(gum style --foreground 27 --bold 'Claude Code Router Configuration')\n\n$(gum style --foreground 240 'Setup your AI model router')\"\n\n echo \"\"\n\n # Check if config exists\n if [[ -f \"$CCR_CONFIG_FILE\" ]]; then\n if ! gum confirm \"Configuration exists. Overwrite?\" --default=false; then\n return 0\n fi\n fi\n\n # Basic settings\n echo \"$(gum style --foreground 141 --bold '1. Basic Settings')\"\n echo \"\"\n\n local host\n host=$(gum input --placeholder \"127.0.0.1\" --value \"127.0.0.1\" --prompt \"Host: \")\n\n local enable_apikey\n enable_apikey=$(gum choose --header \"Enable API key authentication?\" \"No\" \"Yes\")\n\n local apikey=\"\"\n if [[ \"$enable_apikey\" == \"Yes\" ]]; then\n apikey=$(gum input --prompt \"API Key: \" --password)\n fi\n\n # Proxy settings\n echo \"\"\n echo \"$(gum style --foreground 141 --bold '2. Network Settings')\"\n echo \"\"\n\n local proxy=\"\"\n if gum confirm \"Use HTTP proxy?\" --default=false; then\n proxy=$(gum input --prompt \"Proxy URL: \" --placeholder \"http://127.0.0.1:7890\")\n fi\n\n # Provider selection\n echo \"\"\n echo \"$(gum style --foreground 141 --bold '3. Provider Setup')\"\n echo \"\"\n\n local providers\n providers=$(gum choose --no-limit --header \"Select providers to configure:\" \\\n \"OpenRouter\" \\\n \"DeepSeek\" \\\n \"OpenAI\" \\\n \"Gemini\" \\\n \"Anthropic\")\n\n # Build config\n cat > \"$CCR_CONFIG_FILE\" << EOF\n{\n \"LOG\": true,\n \"LOG_LEVEL\": \"debug\",\n \"API_TIMEOUT_MS\": 600000,\n \"NON_INTERACTIVE_MODE\": false,\n \"HOST\": \"$host\",\n \"APIKEY\": \"$apikey\",\n \"PROXY_URL\": \"$proxy\",\n \"Providers\": [\nEOF\n\n local first=true\n\n # Add providers\n if echo \"$providers\" | grep -q \"OpenRouter\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"openrouter\",\n \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n \"api_key\": \"$OPENROUTER_API_KEY\",\n \"models\": [\n \"anthropic/claude-sonnet-4\",\n \"anthropic/claude-3.5-sonnet\",\n \"google/gemini-2.5-pro-preview\"\n ],\n \"transformer\": {\n \"use\": [\"openrouter\"]\n }\n }\nEOF\n first=false\n fi\n\n if echo \"$providers\" | grep -q \"DeepSeek\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"$DEEPSEEK_API_KEY\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": {\n \"use\": [\"deepseek\"],\n \"deepseek-chat\": {\n \"use\": [\"tooluse\"]\n }\n }\n }\nEOF\n first=false\n fi\n\n if echo \"$providers\" | grep -q \"OpenAI\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"openai\",\n \"api_base_url\": \"https://api.openai.com/v1/chat/completions\",\n \"api_key\": \"$OPENAI_API_KEY\",\n \"models\": [\"gpt-5\", \"gpt-5-mini\"]\n }\nEOF\n first=false\n fi\n\n if echo \"$providers\" | grep -q \"Gemini\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"gemini\",\n \"api_base_url\": \"https://generativelanguage.googleapis.com/v1beta/models/\",\n \"api_key\": \"$GEMINI_API_KEY\",\n \"models\": [\"gemini-2.5-flash\", \"gemini-2.5-pro\"],\n \"transformer\": {\n \"use\": [\"gemini\"]\n }\n }\nEOF\n first=false\n fi\n\n if echo \"$providers\" | grep -q \"Anthropic\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"anthropic\",\n \"api_base_url\": \"https://api.anthropic.com/v1/messages\",\n \"api_key\": \"$ANTHROPIC_API_KEY\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-3-5-sonnet-20241022\"],\n \"transformer\": {\n \"use\": [\"anthropic\"]\n }\n }\nEOF\n first=false\n fi\n\n # Close providers array and add router\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"background\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\",\n \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n \"longContextThreshold\": 60000\n }\n}\nEOF\n\n echo \"\"\n gum style --foreground 34 --bold \"✓ Configuration saved!\"\n echo \"\"\n echo \"Next steps:\"\n echo \" 1. Set API keys as environment variables\"\n echo \" 2. Run: flox activate -s\"\n echo \" 3. Configure Claude Code API base URL to: http://$host:3456\"\n}\n\n# Helper: Show configuration status\nccr-status() {\n echo \"Claude Code Router Status\"\n echo \"\"\n echo \"✓ ccr: $(which ccr)\"\n echo \"\"\n\n # Check config\n if [[ -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"✓ Config exists: $CCR_CONFIG_FILE\"\n\n # Show providers\n if command -v jq &> /dev/null; then\n echo \"\"\n echo \"Configured Providers:\"\n jq -r '.Providers[]?.name // empty' \"$CCR_CONFIG_FILE\" | sed 's/^/ - /'\n\n echo \"\"\n echo \"Router Settings:\"\n jq -r '.Router | to_entries[] | \" \\(.key): \\(.value)\"' \"$CCR_CONFIG_FILE\"\n fi\n else\n echo \"✗ No config found\"\n fi\n\n echo \"\"\n\n # Check if service is running\n if pgrep -f \"claude-code-router\" > /dev/null; then\n echo \"✓ Service is running\"\n else\n echo \"⚠️ Service not running (start with: flox activate -s)\"\n fi\n}\n\n# Helper: View logs\nccr-logs() {\n if [[ -f \"$CCR_LOG_DIR/claude-code-router.log\" ]]; then\n tail -f \"$CCR_LOG_DIR/claude-code-router.log\"\n else\n echo \"No logs found at $CCR_LOG_DIR/claude-code-router.log\"\n fi\n}\n\n# Helper: Edit configuration\nccr-edit() {\n local editor=\"${EDITOR:-nano}\"\n\n if [[ ! -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"No config found. Creating example...\"\n ccr-config-example\n fi\n\n \"$editor\" \"$CCR_CONFIG_FILE\"\n\n echo \"\"\n echo \"Configuration updated. Restart service:\"\n echo \" flox services restart ccr\"\n}\n\n# Helper: Test connection\nccr-test() {\n local endpoint=\"${1:-http://$CCR_HOST:$CCR_PORT}\"\n\n echo \"Testing connection to $endpoint...\"\n\n if curl -s \"$endpoint/health\" > /dev/null 2>&1; then\n echo \"✓ Router is reachable\"\n return 0\n else\n echo \"✗ Router is not reachable\"\n echo \"\"\n echo \"Make sure the service is running:\"\n echo \" flox activate -s\"\n return 1\n fi\n}\n\n# Export functions\nexport -f ccr-config-example ccr-setup ccr-status ccr-logs ccr-edit ccr-test\n'''\n\nzsh = '''\n# Helper: Generate example configuration\nccr-config-example() {\n local config_file=\"${1:-$CCR_CONFIG_FILE}\"\n\n cat > \"$config_file\" << 'EOF'\n{\n \"LOG\": true,\n \"LOG_LEVEL\": \"debug\",\n \"API_TIMEOUT_MS\": 600000,\n \"NON_INTERACTIVE_MODE\": false,\n \"APIKEY\": \"\",\n \"HOST\": \"127.0.0.1\",\n \"PROXY_URL\": \"\",\n \"Providers\": [\n {\n \"name\": \"openrouter\",\n \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n \"api_key\": \"$OPENROUTER_API_KEY\",\n \"models\": [\n \"anthropic/claude-sonnet-4\",\n \"anthropic/claude-3.5-sonnet\",\n \"google/gemini-2.5-pro-preview\"\n ],\n \"transformer\": {\n \"use\": [\"openrouter\"]\n }\n },\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"$DEEPSEEK_API_KEY\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": {\n \"use\": [\"deepseek\"],\n \"deepseek-chat\": {\n \"use\": [\"tooluse\"]\n }\n }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"background\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\",\n \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n \"longContextThreshold\": 60000\n }\n}\nEOF\n\n echo \"✓ Example configuration created: $config_file\"\n echo \"\"\n echo \"Edit with: ${EDITOR:-nano} $config_file\"\n echo \"Or use: ccr-setup (interactive wizard)\"\n}\n\n# Helper: Interactive configuration wizard\nccr-setup() {\n if ! command -v gum &> /dev/null; then\n echo \"⚠️ gum not found. Using non-interactive mode.\"\n ccr-config-example\n return 0\n fi\n\n clear\n\n gum style \\\n --border rounded \\\n --border-foreground 240 \\\n --padding \"1 2\" \\\n --margin \"1 0\" \\\n --width 70 \\\n \"$(gum style --foreground 27 --bold 'Claude Code Router Configuration')\n\n$(gum style --foreground 240 'Setup your AI model router')\"\n\n echo \"\"\n\n # Check if config exists\n if [[ -f \"$CCR_CONFIG_FILE\" ]]; then\n if ! gum confirm \"Configuration exists. Overwrite?\" --default=false; then\n return 0\n fi\n fi\n\n # Basic settings\n echo \"$(gum style --foreground 141 --bold '1. Basic Settings')\"\n echo \"\"\n\n local host\n host=$(gum input --placeholder \"127.0.0.1\" --value \"127.0.0.1\" --prompt \"Host: \")\n\n local enable_apikey\n enable_apikey=$(gum choose --header \"Enable API key authentication?\" \"No\" \"Yes\")\n\n local apikey=\"\"\n if [[ \"$enable_apikey\" == \"Yes\" ]]; then\n apikey=$(gum input --prompt \"API Key: \" --password)\n fi\n\n # Proxy settings\n echo \"\"\n echo \"$(gum style --foreground 141 --bold '2. Network Settings')\"\n echo \"\"\n\n local proxy=\"\"\n if gum confirm \"Use HTTP proxy?\" --default=false; then\n proxy=$(gum input --prompt \"Proxy URL: \" --placeholder \"http://127.0.0.1:7890\")\n fi\n\n # Provider selection\n echo \"\"\n echo \"$(gum style --foreground 141 --bold '3. Provider Setup')\"\n echo \"\"\n\n local providers\n providers=$(gum choose --no-limit --header \"Select providers to configure:\" \\\n \"OpenRouter\" \\\n \"DeepSeek\" \\\n \"OpenAI\" \\\n \"Gemini\" \\\n \"Anthropic\")\n\n # Build config (same as bash version)\n # ... [similar implementation]\n\n echo \"\"\n gum style --foreground 34 --bold \"✓ Configuration saved!\"\n}\n\n# Helper: Show configuration status\nccr-status() {\n echo \"Claude Code Router Status\"\n echo \"\"\n echo \"✓ ccr: $(which ccr)\"\n echo \"\"\n\n if [[ -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"✓ Config exists: $CCR_CONFIG_FILE\"\n\n if command -v jq &> /dev/null; then\n echo \"\"\n echo \"Configured Providers:\"\n jq -r '.Providers[]?.name // empty' \"$CCR_CONFIG_FILE\" | sed 's/^/ - /'\n\n echo \"\"\n echo \"Router Settings:\"\n jq -r '.Router | to_entries[] | \" \\(.key): \\(.value)\"' \"$CCR_CONFIG_FILE\"\n fi\n else\n echo \"✗ No config found\"\n fi\n\n echo \"\"\n\n if pgrep -f \"claude-code-router\" > /dev/null; then\n echo \"✓ Service is running\"\n else\n echo \"⚠️ Service not running (start with: flox activate -s)\"\n fi\n}\n\n# Helper: View logs\nccr-logs() {\n if [[ -f \"$CCR_LOG_DIR/claude-code-router.log\" ]]; then\n tail -f \"$CCR_LOG_DIR/claude-code-router.log\"\n else\n echo \"No logs found at $CCR_LOG_DIR/claude-code-router.log\"\n fi\n}\n\n# Helper: Edit configuration\nccr-edit() {\n local editor=\"${EDITOR:-nano}\"\n\n if [[ ! -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"No config found. Creating example...\"\n ccr-config-example\n fi\n\n \"$editor\" \"$CCR_CONFIG_FILE\"\n\n echo \"\"\n echo \"Configuration updated. Restart service:\"\n echo \" flox services restart ccr\"\n}\n\n# Helper: Test connection\nccr-test() {\n local endpoint=\"${1:-http://$CCR_HOST:$CCR_PORT}\"\n\n echo \"Testing connection to $endpoint...\"\n\n if curl -s \"$endpoint/health\" > /dev/null 2>&1; then\n echo \"✓ Router is reachable\"\n return 0\n else\n echo \"✗ Router is not reachable\"\n echo \"\"\n echo \"Make sure the service is running:\"\n echo \" flox activate -s\"\n return 1\n fi\n}\n'''\n\nfish = '''\n# Helper: Generate example configuration\nfunction ccr-config-example\n set config_file (test -n \"$argv[1]\"; and echo \"$argv[1]\"; or echo \"$CCR_CONFIG_FILE\")\n\n cat > \"$config_file\" << 'EOF'\n{\n \"LOG\": true,\n \"LOG_LEVEL\": \"debug\",\n \"API_TIMEOUT_MS\": 600000,\n \"NON_INTERACTIVE_MODE\": false,\n \"APIKEY\": \"\",\n \"HOST\": \"127.0.0.1\",\n \"PROXY_URL\": \"\",\n \"Providers\": [\n {\n \"name\": \"openrouter\",\n \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n \"api_key\": \"$OPENROUTER_API_KEY\",\n \"models\": [\n \"anthropic/claude-sonnet-4\",\n \"anthropic/claude-3.5-sonnet\",\n \"google/gemini-2.5-pro-preview\"\n ],\n \"transformer\": {\n \"use\": [\"openrouter\"]\n }\n },\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"$DEEPSEEK_API_KEY\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": {\n \"use\": [\"deepseek\"],\n \"deepseek-chat\": {\n \"use\": [\"tooluse\"]\n }\n }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"background\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\",\n \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n \"longContextThreshold\": 60000\n }\n}\nEOF\n\n echo \"✓ Example configuration created: $config_file\"\n echo \"\"\n echo \"Edit with: \"(set -q EDITOR; and echo $EDITOR; or echo \"nano\")\" $config_file\"\n echo \"Or use: ccr-setup (interactive wizard)\"\nend\n\n# Helper: Show configuration status\nfunction ccr-status\n echo \"Claude Code Router Status\"\n echo \"\"\n echo \"✓ ccr: \"(which ccr)\n echo \"\"\n\n if test -f \"$CCR_CONFIG_FILE\"\n echo \"✓ Config exists: $CCR_CONFIG_FILE\"\n\n if command -v jq &> /dev/null\n echo \"\"\n echo \"Configured Providers:\"\n jq -r '.Providers[]?.name // empty' \"$CCR_CONFIG_FILE\" | sed 's/^/ - /'\n\n echo \"\"\n echo \"Router Settings:\"\n jq -r '.Router | to_entries[] | \" \\(.key): \\(.value)\"' \"$CCR_CONFIG_FILE\"\n end\n else\n echo \"✗ No config found\"\n end\n\n echo \"\"\n\n if pgrep -f \"claude-code-router\" > /dev/null\n echo \"✓ Service is running\"\n else\n echo \"⚠️ Service not running (start with: flox activate -s)\"\n end\nend\n\n# Helper: View logs\nfunction ccr-logs\n if test -f \"$CCR_LOG_DIR/claude-code-router.log\"\n tail -f \"$CCR_LOG_DIR/claude-code-router.log\"\n else\n echo \"No logs found at $CCR_LOG_DIR/claude-code-router.log\"\n end\nend\n\n# Helper: Edit configuration\nfunction ccr-edit\n set editor (set -q EDITOR; and echo $EDITOR; or echo \"nano\")\n\n if not test -f \"$CCR_CONFIG_FILE\"\n echo \"No config found. Creating example...\"\n ccr-config-example\n end\n\n eval $editor \"$CCR_CONFIG_FILE\"\n\n echo \"\"\n echo \"Configuration updated. Restart service:\"\n echo \" flox services restart ccr\"\nend\n\n# Helper: Test connection\nfunction ccr-test\n set endpoint (test -n \"$argv[1]\"; and echo \"$argv[1]\"; or echo \"http://$CCR_HOST:$CCR_PORT\")\n\n echo \"Testing connection to $endpoint...\"\n\n if curl -s \"$endpoint/health\" > /dev/null 2>&1\n echo \"✓ Router is reachable\"\n return 0\n else\n echo \"✗ Router is not reachable\"\n echo \"\"\n echo \"Make sure the service is running:\"\n echo \" flox activate -s\"\n return 1\n end\nend\n'''\n\n\n## Services ----------------------------------------------------------\n[services]\nccr.is-daemon = true\nccr.shutdown = { command = \"ccr stop\" }\nccr.command = '''\n# Load environment variables\nexport CCR_HOST=\"${CCR_HOST}\"\nexport CCR_PORT=\"${CCR_PORT}\"\nexport CCR_APIKEY=\"${CCR_APIKEY}\"\nexport CCR_PROXY_URL=\"${CCR_PROXY_URL}\"\nexport CCR_LOG_ENABLED=\"${CCR_LOG_ENABLED}\"\nexport CCR_LOG_LEVEL=\"${CCR_LOG_LEVEL}\"\nexport CCR_API_TIMEOUT_MS=\"${CCR_API_TIMEOUT_MS}\"\nexport CCR_NON_INTERACTIVE=\"${CCR_NON_INTERACTIVE}\"\n\n# Export API keys\nexport OPENAI_API_KEY=\"${OPENAI_API_KEY}\"\nexport DEEPSEEK_API_KEY=\"${DEEPSEEK_API_KEY}\"\nexport OPENROUTER_API_KEY=\"${OPENROUTER_API_KEY}\"\nexport GEMINI_API_KEY=\"${GEMINI_API_KEY}\"\nexport ANTHROPIC_API_KEY=\"${ANTHROPIC_API_KEY}\"\n\n# Check if config exists\nif [[ ! -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"ERROR: Configuration not found at $CCR_CONFIG_FILE\"\n echo \"Run 'ccr-setup' to create configuration\"\n exit 1\nfi\n\n# Start the router\nexec ccr start\n'''\n\n\n## Other Environment Options -----------------------------------------\n[options]\n# Systems that environment is compatible with\nsystems = [\n \"aarch64-darwin\",\n \"aarch64-linux\",\n \"x86_64-darwin\",\n \"x86_64-linux\",\n]\n"}, "d541752471309b571483acd77f4992049fedc6fc": {"t": 1785750608.893123, "n": 22690, "h": "4b025da1f6a5cd58", "c": "## Flox Environment Manifest -----------------------------------------\n##\n## _Everything_ you need to know about the _manifest_ is here:\n##\n## https://flox.dev/docs/concepts/manifest\n##\n## -------------------------------------------------------------------\n# Flox manifest version managed by Flox CLI\nversion = 1\n\n\n## Included: Local Ollama Service -----------------------------------\n## This environment includes local Ollama LLM support by default via\n## composition with the ollama-headless environment. This allows routing\n## requests to local models for privacy, offline use, and cost savings.\n##\n## To use Ollama:\n## 1. Add Ollama provider to ~/.claude-code-router/config.json:\n## {\n## \"name\": \"ollama\",\n## \"api_base_url\": \"http://localhost:11434/v1/chat/completions\",\n## \"api_key\": \"\",\n## \"models\": [\"qwen2.5-coder:32b\", \"deepseek-r1:32b\", ...]\n## }\n## 2. Start with: flox activate -s (starts both Ollama and router)\n##\n## To run WITHOUT Ollama (cloud providers only):\n## Option A: Comment out the [include] section below\n## Option B: Use 'flox activate' then 'flox services start ccr'\n## (this starts only the router service, not Ollama)\n##\n[include]\nollama = \"barstoolbluz/ollama-headless\"\n\n\n## Install Packages --------------------------------------------------\n[install]\nclaude-code-router.pkg-path = \"claude-code-router\"\nclaude-code.pkg-path = \"claude-code\"\ngum.pkg-path = \"gum\"\ncurl.pkg-path = \"curl\"\njq.pkg-path = \"jq\"\nbat.pkg-path = \"bat\"\n\n\n## Environment Variables ---------------------------------------------\n[vars]\n# Base configuration paths\nCCR_CONFIG_DIR = \"$HOME/.claude-code-router\"\nCCR_LOG_DIR = \"$HOME/.claude-code-router/logs\"\nCCR_CONFIG_FILE = \"$HOME/.claude-code-router/config.json\"\n\n# Runtime-configurable with defaults (headless pattern)\nCCR_HOST = \"${CCR_HOST:-127.0.0.1}\"\nCCR_PORT = \"${CCR_PORT:-3456}\"\nCCR_APIKEY = \"${CCR_APIKEY:-}\"\nCCR_PROXY_URL = \"${CCR_PROXY_URL:-}\"\nCCR_LOG_ENABLED = \"${CCR_LOG_ENABLED:-true}\"\nCCR_LOG_LEVEL = \"${CCR_LOG_LEVEL:-debug}\"\nCCR_API_TIMEOUT_MS = \"${CCR_API_TIMEOUT_MS:-600000}\"\nCCR_NON_INTERACTIVE = \"${CCR_NON_INTERACTIVE:-false}\"\n\n# API Keys (env var injection pattern)\nOPENAI_API_KEY = \"${OPENAI_API_KEY:-}\"\nDEEPSEEK_API_KEY = \"${DEEPSEEK_API_KEY:-}\"\nOPENROUTER_API_KEY = \"${OPENROUTER_API_KEY:-}\"\nGEMINI_API_KEY = \"${GEMINI_API_KEY:-}\"\nANTHROPIC_API_KEY = \"${ANTHROPIC_API_KEY:-}\"\n\n\n## Activation Hook ---------------------------------------------------\n[hook]\non-activate = '''\n# Create required directories\nmkdir -p \"$CCR_CONFIG_DIR\"\nmkdir -p \"$CCR_LOG_DIR\"\nmkdir -p \"$CCR_CONFIG_DIR/plugins\"\n\n# Function to check if config exists\ncheck_ccr_config() {\n [[ -f \"$CCR_CONFIG_FILE\" ]] || return 1\n [[ -s \"$CCR_CONFIG_FILE\" ]] || return 1\n return 0\n}\n\n# Display info\nshow_ccr_info() {\n local config_status\n if check_ccr_config; then\n config_status=\"✓ Configured\"\n else\n config_status=\"⚠️ Not configured\"\n fi\n\n echo \"\"\n echo \"✅ Claude Code Router environment ready (headless mode)\"\n echo \"\"\n echo \"Configuration:\"\n echo \" Config: $CCR_CONFIG_FILE ($config_status)\"\n echo \" Host: $CCR_HOST\"\n echo \" Port: $CCR_PORT\"\n echo \" Logs: $CCR_LOG_DIR\"\n echo \"\"\n echo \"Service Management:\"\n echo \" flox activate -s Start router service\"\n echo \" flox services status Check service status\"\n echo \" flox services logs ccr View service logs\"\n echo \"\"\n echo \"Configuration:\"\n echo \" ccr-setup Interactive config wizard\"\n echo \" ccr-config-example Generate example config\"\n echo \" ccr ui Open web UI for config\"\n echo \" ccr model Interactive model selector\"\n echo \"\"\n echo \"Runtime Customization (via env vars):\"\n echo \" CCR_HOST=0.0.0.0 CCR_APIKEY=secret flox activate -s\"\n echo \"\"\n echo \"Configure Claude Code:\"\n echo \" Set API base URL to: http://$CCR_HOST:$CCR_PORT\"\n echo \" ccr ui Open config UI in browser\"\n echo \"\"\n}\n\n# Main initialization\nif ! check_ccr_config; then\n echo \"ℹ️ No configuration found. Run 'ccr-setup' to create one.\"\nfi\n\nshow_ccr_info\n'''\n\n\n## Profile script ----------------------------------------------------\n[profile]\nbash = '''\n# Helper: Generate example configuration\nccr-config-example() {\n local config_file=\"${1:-$CCR_CONFIG_FILE}\"\n\n cat > \"$config_file\" << 'EOF'\n{\n \"LOG\": true,\n \"LOG_LEVEL\": \"debug\",\n \"API_TIMEOUT_MS\": 600000,\n \"NON_INTERACTIVE_MODE\": false,\n \"APIKEY\": \"\",\n \"HOST\": \"127.0.0.1\",\n \"PROXY_URL\": \"\",\n \"Providers\": [\n {\n \"name\": \"openrouter\",\n \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n \"api_key\": \"$OPENROUTER_API_KEY\",\n \"models\": [\n \"anthropic/claude-sonnet-4\",\n \"anthropic/claude-3.5-sonnet\",\n \"google/gemini-2.5-pro-preview\"\n ],\n \"transformer\": {\n \"use\": [\"openrouter\"]\n }\n },\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"$DEEPSEEK_API_KEY\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": {\n \"use\": [\"deepseek\"],\n \"deepseek-chat\": {\n \"use\": [\"tooluse\"]\n }\n }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"background\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\",\n \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n \"longContextThreshold\": 60000\n }\n}\nEOF\n\n echo \"✓ Example configuration created: $config_file\"\n echo \"\"\n echo \"Edit with: ${EDITOR:-nano} $config_file\"\n echo \"Or use: ccr-setup (interactive wizard)\"\n}\n\n# Helper: Interactive configuration wizard\nccr-setup() {\n if ! command -v gum &> /dev/null; then\n echo \"⚠️ gum not found. Using non-interactive mode.\"\n ccr-config-example\n return 0\n fi\n\n clear\n\n gum style \\\n --border rounded \\\n --border-foreground 240 \\\n --padding \"1 2\" \\\n --margin \"1 0\" \\\n --width 70 \\\n \"$(gum style --foreground 27 --bold 'Claude Code Router Configuration')\n\n$(gum style --foreground 240 'Setup your AI model router')\"\n\n echo \"\"\n\n # Check if config exists\n if [[ -f \"$CCR_CONFIG_FILE\" ]]; then\n if ! gum confirm \"Configuration exists. Overwrite?\" --default=false; then\n return 0\n fi\n fi\n\n # Basic settings\n echo \"$(gum style --foreground 141 --bold '1. Basic Settings')\"\n echo \"\"\n\n local host\n host=$(gum input --placeholder \"127.0.0.1\" --value \"127.0.0.1\" --prompt \"Host: \")\n\n local enable_apikey\n enable_apikey=$(gum choose --header \"Enable API key authentication?\" \"No\" \"Yes\")\n\n local apikey=\"\"\n if [[ \"$enable_apikey\" == \"Yes\" ]]; then\n apikey=$(gum input --prompt \"API Key: \" --password)\n fi\n\n # Proxy settings\n echo \"\"\n echo \"$(gum style --foreground 141 --bold '2. Network Settings')\"\n echo \"\"\n\n local proxy=\"\"\n if gum confirm \"Use HTTP proxy?\" --default=false; then\n proxy=$(gum input --prompt \"Proxy URL: \" --placeholder \"http://127.0.0.1:7890\")\n fi\n\n # Provider selection\n echo \"\"\n echo \"$(gum style --foreground 141 --bold '3. Provider Setup')\"\n echo \"\"\n\n local providers\n providers=$(gum choose --no-limit --header \"Select providers to configure:\" \\\n \"OpenRouter\" \\\n \"DeepSeek\" \\\n \"OpenAI\" \\\n \"Gemini\" \\\n \"Anthropic\")\n\n # Build config\n cat > \"$CCR_CONFIG_FILE\" << EOF\n{\n \"LOG\": true,\n \"LOG_LEVEL\": \"debug\",\n \"API_TIMEOUT_MS\": 600000,\n \"NON_INTERACTIVE_MODE\": false,\n \"HOST\": \"$host\",\n \"APIKEY\": \"$apikey\",\n \"PROXY_URL\": \"$proxy\",\n \"Providers\": [\nEOF\n\n local first=true\n\n # Add providers\n if echo \"$providers\" | grep -q \"OpenRouter\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"openrouter\",\n \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n \"api_key\": \"$OPENROUTER_API_KEY\",\n \"models\": [\n \"anthropic/claude-sonnet-4\",\n \"anthropic/claude-3.5-sonnet\",\n \"google/gemini-2.5-pro-preview\"\n ],\n \"transformer\": {\n \"use\": [\"openrouter\"]\n }\n }\nEOF\n first=false\n fi\n\n if echo \"$providers\" | grep -q \"DeepSeek\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"$DEEPSEEK_API_KEY\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": {\n \"use\": [\"deepseek\"],\n \"deepseek-chat\": {\n \"use\": [\"tooluse\"]\n }\n }\n }\nEOF\n first=false\n fi\n\n if echo \"$providers\" | grep -q \"OpenAI\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"openai\",\n \"api_base_url\": \"https://api.openai.com/v1/chat/completions\",\n \"api_key\": \"$OPENAI_API_KEY\",\n \"models\": [\"gpt-5\", \"gpt-5-mini\"]\n }\nEOF\n first=false\n fi\n\n if echo \"$providers\" | grep -q \"Gemini\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"gemini\",\n \"api_base_url\": \"https://generativelanguage.googleapis.com/v1beta/models/\",\n \"api_key\": \"$GEMINI_API_KEY\",\n \"models\": [\"gemini-2.5-flash\", \"gemini-2.5-pro\"],\n \"transformer\": {\n \"use\": [\"gemini\"]\n }\n }\nEOF\n first=false\n fi\n\n if echo \"$providers\" | grep -q \"Anthropic\"; then\n [[ \"$first\" == \"false\" ]] && echo \",\" >> \"$CCR_CONFIG_FILE\"\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n {\n \"name\": \"anthropic\",\n \"api_base_url\": \"https://api.anthropic.com/v1/messages\",\n \"api_key\": \"$ANTHROPIC_API_KEY\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-3-5-sonnet-20241022\"],\n \"transformer\": {\n \"use\": [\"anthropic\"]\n }\n }\nEOF\n first=false\n fi\n\n # Close providers array and add router\n cat >> \"$CCR_CONFIG_FILE\" << 'EOF'\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"background\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\",\n \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n \"longContextThreshold\": 60000\n }\n}\nEOF\n\n echo \"\"\n gum style --foreground 34 --bold \"✓ Configuration saved!\"\n echo \"\"\n echo \"Next steps:\"\n echo \" 1. Set API keys as environment variables\"\n echo \" 2. Run: flox activate -s\"\n echo \" 3. Configure Claude Code API base URL to: http://$host:3456\"\n}\n\n# Helper: Show configuration status\nccr-status() {\n echo \"Claude Code Router Status\"\n echo \"\"\n echo \"✓ ccr: $(which ccr)\"\n echo \"\"\n\n # Check config\n if [[ -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"✓ Config exists: $CCR_CONFIG_FILE\"\n\n # Show providers\n if command -v jq &> /dev/null; then\n echo \"\"\n echo \"Configured Providers:\"\n jq -r '.Providers[]?.name // empty' \"$CCR_CONFIG_FILE\" | sed 's/^/ - /'\n\n echo \"\"\n echo \"Router Settings:\"\n jq -r '.Router | to_entries[] | \" \\(.key): \\(.value)\"' \"$CCR_CONFIG_FILE\"\n fi\n else\n echo \"✗ No config found\"\n fi\n\n echo \"\"\n\n # Check if service is running\n if pgrep -f \"claude-code-router\" > /dev/null; then\n echo \"✓ Service is running\"\n else\n echo \"⚠️ Service not running (start with: flox activate -s)\"\n fi\n}\n\n# Helper: View logs\nccr-logs() {\n if [[ -f \"$CCR_LOG_DIR/claude-code-router.log\" ]]; then\n tail -f \"$CCR_LOG_DIR/claude-code-router.log\"\n else\n echo \"No logs found at $CCR_LOG_DIR/claude-code-router.log\"\n fi\n}\n\n# Helper: Edit configuration\nccr-edit() {\n local editor=\"${EDITOR:-nano}\"\n\n if [[ ! -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"No config found. Creating example...\"\n ccr-config-example\n fi\n\n \"$editor\" \"$CCR_CONFIG_FILE\"\n\n echo \"\"\n echo \"Configuration updated. Restart service:\"\n echo \" flox services restart ccr\"\n}\n\n# Helper: Test connection\nccr-test() {\n local endpoint=\"${1:-http://$CCR_HOST:$CCR_PORT}\"\n\n echo \"Testing connection to $endpoint...\"\n\n if curl -s \"$endpoint/health\" > /dev/null 2>&1; then\n echo \"✓ Router is reachable\"\n return 0\n else\n echo \"✗ Router is not reachable\"\n echo \"\"\n echo \"Make sure the service is running:\"\n echo \" flox activate -s\"\n return 1\n fi\n}\n\n# Export functions\nexport -f ccr-config-example ccr-setup ccr-status ccr-logs ccr-edit ccr-test\n'''\n\nzsh = '''\n# Helper: Generate example configuration\nccr-config-example() {\n local config_file=\"${1:-$CCR_CONFIG_FILE}\"\n\n cat > \"$config_file\" << 'EOF'\n{\n \"LOG\": true,\n \"LOG_LEVEL\": \"debug\",\n \"API_TIMEOUT_MS\": 600000,\n \"NON_INTERACTIVE_MODE\": false,\n \"APIKEY\": \"\",\n \"HOST\": \"127.0.0.1\",\n \"PROXY_URL\": \"\",\n \"Providers\": [\n {\n \"name\": \"openrouter\",\n \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n \"api_key\": \"$OPENROUTER_API_KEY\",\n \"models\": [\n \"anthropic/claude-sonnet-4\",\n \"anthropic/claude-3.5-sonnet\",\n \"google/gemini-2.5-pro-preview\"\n ],\n \"transformer\": {\n \"use\": [\"openrouter\"]\n }\n },\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"$DEEPSEEK_API_KEY\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": {\n \"use\": [\"deepseek\"],\n \"deepseek-chat\": {\n \"use\": [\"tooluse\"]\n }\n }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"background\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\",\n \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n \"longContextThreshold\": 60000\n }\n}\nEOF\n\n echo \"✓ Example configuration created: $config_file\"\n echo \"\"\n echo \"Edit with: ${EDITOR:-nano} $config_file\"\n echo \"Or use: ccr-setup (interactive wizard)\"\n}\n\n# Helper: Interactive configuration wizard\nccr-setup() {\n if ! command -v gum &> /dev/null; then\n echo \"⚠️ gum not found. Using non-interactive mode.\"\n ccr-config-example\n return 0\n fi\n\n clear\n\n gum style \\\n --border rounded \\\n --border-foreground 240 \\\n --padding \"1 2\" \\\n --margin \"1 0\" \\\n --width 70 \\\n \"$(gum style --foreground 27 --bold 'Claude Code Router Configuration')\n\n$(gum style --foreground 240 'Setup your AI model router')\"\n\n echo \"\"\n\n # Check if config exists\n if [[ -f \"$CCR_CONFIG_FILE\" ]]; then\n if ! gum confirm \"Configuration exists. Overwrite?\" --default=false; then\n return 0\n fi\n fi\n\n # Basic settings\n echo \"$(gum style --foreground 141 --bold '1. Basic Settings')\"\n echo \"\"\n\n local host\n host=$(gum input --placeholder \"127.0.0.1\" --value \"127.0.0.1\" --prompt \"Host: \")\n\n local enable_apikey\n enable_apikey=$(gum choose --header \"Enable API key authentication?\" \"No\" \"Yes\")\n\n local apikey=\"\"\n if [[ \"$enable_apikey\" == \"Yes\" ]]; then\n apikey=$(gum input --prompt \"API Key: \" --password)\n fi\n\n # Proxy settings\n echo \"\"\n echo \"$(gum style --foreground 141 --bold '2. Network Settings')\"\n echo \"\"\n\n local proxy=\"\"\n if gum confirm \"Use HTTP proxy?\" --default=false; then\n proxy=$(gum input --prompt \"Proxy URL: \" --placeholder \"http://127.0.0.1:7890\")\n fi\n\n # Provider selection\n echo \"\"\n echo \"$(gum style --foreground 141 --bold '3. Provider Setup')\"\n echo \"\"\n\n local providers\n providers=$(gum choose --no-limit --header \"Select providers to configure:\" \\\n \"OpenRouter\" \\\n \"DeepSeek\" \\\n \"OpenAI\" \\\n \"Gemini\" \\\n \"Anthropic\")\n\n # Build config (same as bash version)\n # ... [similar implementation]\n\n echo \"\"\n gum style --foreground 34 --bold \"✓ Configuration saved!\"\n}\n\n# Helper: Show configuration status\nccr-status() {\n echo \"Claude Code Router Status\"\n echo \"\"\n echo \"✓ ccr: $(which ccr)\"\n echo \"\"\n\n if [[ -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"✓ Config exists: $CCR_CONFIG_FILE\"\n\n if command -v jq &> /dev/null; then\n echo \"\"\n echo \"Configured Providers:\"\n jq -r '.Providers[]?.name // empty' \"$CCR_CONFIG_FILE\" | sed 's/^/ - /'\n\n echo \"\"\n echo \"Router Settings:\"\n jq -r '.Router | to_entries[] | \" \\(.key): \\(.value)\"' \"$CCR_CONFIG_FILE\"\n fi\n else\n echo \"✗ No config found\"\n fi\n\n echo \"\"\n\n if pgrep -f \"claude-code-router\" > /dev/null; then\n echo \"✓ Service is running\"\n else\n echo \"⚠️ Service not running (start with: flox activate -s)\"\n fi\n}\n\n# Helper: View logs\nccr-logs() {\n if [[ -f \"$CCR_LOG_DIR/claude-code-router.log\" ]]; then\n tail -f \"$CCR_LOG_DIR/claude-code-router.log\"\n else\n echo \"No logs found at $CCR_LOG_DIR/claude-code-router.log\"\n fi\n}\n\n# Helper: Edit configuration\nccr-edit() {\n local editor=\"${EDITOR:-nano}\"\n\n if [[ ! -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"No config found. Creating example...\"\n ccr-config-example\n fi\n\n \"$editor\" \"$CCR_CONFIG_FILE\"\n\n echo \"\"\n echo \"Configuration updated. Restart service:\"\n echo \" flox services restart ccr\"\n}\n\n# Helper: Test connection\nccr-test() {\n local endpoint=\"${1:-http://$CCR_HOST:$CCR_PORT}\"\n\n echo \"Testing connection to $endpoint...\"\n\n if curl -s \"$endpoint/health\" > /dev/null 2>&1; then\n echo \"✓ Router is reachable\"\n return 0\n else\n echo \"✗ Router is not reachable\"\n echo \"\"\n echo \"Make sure the service is running:\"\n echo \" flox activate -s\"\n return 1\n fi\n}\n'''\n\nfish = '''\n# Helper: Generate example configuration\nfunction ccr-config-example\n set config_file (test -n \"$argv[1]\"; and echo \"$argv[1]\"; or echo \"$CCR_CONFIG_FILE\")\n\n cat > \"$config_file\" << 'EOF'\n{\n \"LOG\": true,\n \"LOG_LEVEL\": \"debug\",\n \"API_TIMEOUT_MS\": 600000,\n \"NON_INTERACTIVE_MODE\": false,\n \"APIKEY\": \"\",\n \"HOST\": \"127.0.0.1\",\n \"PROXY_URL\": \"\",\n \"Providers\": [\n {\n \"name\": \"openrouter\",\n \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n \"api_key\": \"$OPENROUTER_API_KEY\",\n \"models\": [\n \"anthropic/claude-sonnet-4\",\n \"anthropic/claude-3.5-sonnet\",\n \"google/gemini-2.5-pro-preview\"\n ],\n \"transformer\": {\n \"use\": [\"openrouter\"]\n }\n },\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"$DEEPSEEK_API_KEY\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": {\n \"use\": [\"deepseek\"],\n \"deepseek-chat\": {\n \"use\": [\"tooluse\"]\n }\n }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"background\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\",\n \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n \"longContextThreshold\": 60000\n }\n}\nEOF\n\n echo \"✓ Example configuration created: $config_file\"\n echo \"\"\n echo \"Edit with: \"(set -q EDITOR; and echo $EDITOR; or echo \"nano\")\" $config_file\"\n echo \"Or use: ccr-setup (interactive wizard)\"\nend\n\n# Helper: Show configuration status\nfunction ccr-status\n echo \"Claude Code Router Status\"\n echo \"\"\n echo \"✓ ccr: \"(which ccr)\n echo \"\"\n\n if test -f \"$CCR_CONFIG_FILE\"\n echo \"✓ Config exists: $CCR_CONFIG_FILE\"\n\n if command -v jq &> /dev/null\n echo \"\"\n echo \"Configured Providers:\"\n jq -r '.Providers[]?.name // empty' \"$CCR_CONFIG_FILE\" | sed 's/^/ - /'\n\n echo \"\"\n echo \"Router Settings:\"\n jq -r '.Router | to_entries[] | \" \\(.key): \\(.value)\"' \"$CCR_CONFIG_FILE\"\n end\n else\n echo \"✗ No config found\"\n end\n\n echo \"\"\n\n if pgrep -f \"claude-code-router\" > /dev/null\n echo \"✓ Service is running\"\n else\n echo \"⚠️ Service not running (start with: flox activate -s)\"\n end\nend\n\n# Helper: View logs\nfunction ccr-logs\n if test -f \"$CCR_LOG_DIR/claude-code-router.log\"\n tail -f \"$CCR_LOG_DIR/claude-code-router.log\"\n else\n echo \"No logs found at $CCR_LOG_DIR/claude-code-router.log\"\n end\nend\n\n# Helper: Edit configuration\nfunction ccr-edit\n set editor (set -q EDITOR; and echo $EDITOR; or echo \"nano\")\n\n if not test -f \"$CCR_CONFIG_FILE\"\n echo \"No config found. Creating example...\"\n ccr-config-example\n end\n\n eval $editor \"$CCR_CONFIG_FILE\"\n\n echo \"\"\n echo \"Configuration updated. Restart service:\"\n echo \" flox services restart ccr\"\nend\n\n# Helper: Test connection\nfunction ccr-test\n set endpoint (test -n \"$argv[1]\"; and echo \"$argv[1]\"; or echo \"http://$CCR_HOST:$CCR_PORT\")\n\n echo \"Testing connection to $endpoint...\"\n\n if curl -s \"$endpoint/health\" > /dev/null 2>&1\n echo \"✓ Router is reachable\"\n return 0\n else\n echo \"✗ Router is not reachable\"\n echo \"\"\n echo \"Make sure the service is running:\"\n echo \" flox activate -s\"\n return 1\n end\nend\n'''\n\n\n## Services ----------------------------------------------------------\n[services]\nccr.is-daemon = true\nccr.shutdown = { command = \"ccr stop\" }\nccr.command = '''\n# Load environment variables\nexport CCR_HOST=\"${CCR_HOST}\"\nexport CCR_PORT=\"${CCR_PORT}\"\nexport CCR_APIKEY=\"${CCR_APIKEY}\"\nexport CCR_PROXY_URL=\"${CCR_PROXY_URL}\"\nexport CCR_LOG_ENABLED=\"${CCR_LOG_ENABLED}\"\nexport CCR_LOG_LEVEL=\"${CCR_LOG_LEVEL}\"\nexport CCR_API_TIMEOUT_MS=\"${CCR_API_TIMEOUT_MS}\"\nexport CCR_NON_INTERACTIVE=\"${CCR_NON_INTERACTIVE}\"\n\n# Export API keys\nexport OPENAI_API_KEY=\"${OPENAI_API_KEY}\"\nexport DEEPSEEK_API_KEY=\"${DEEPSEEK_API_KEY}\"\nexport OPENROUTER_API_KEY=\"${OPENROUTER_API_KEY}\"\nexport GEMINI_API_KEY=\"${GEMINI_API_KEY}\"\nexport ANTHROPIC_API_KEY=\"${ANTHROPIC_API_KEY}\"\n\n# Check if config exists\nif [[ ! -f \"$CCR_CONFIG_FILE\" ]]; then\n echo \"ERROR: Configuration not found at $CCR_CONFIG_FILE\"\n echo \"Run 'ccr-setup' to create configuration\"\n exit 1\nfi\n\n# Start the router\nexec ccr start\n'''\n\n\n## Other Environment Options -----------------------------------------\n[options]\n# Systems that environment is compatible with\nsystems = [\n \"aarch64-darwin\",\n \"aarch64-linux\",\n \"x86_64-darwin\",\n \"x86_64-linux\",\n]\n"}}}}