Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/barstoolbluz_agentic-development-with-flox.json

1 line
98 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"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"}}}}