1 line
39 KiB
JSON
1 line
39 KiB
JSON
{"repo": "cadot-eu/deepseek-bash", "files": {"dp": {"7ef239d46a24a3979274ae5eb15580c85188096b": {"t": 1785746522.1108227, "n": 18522, "h": "adcbf584c76e643f", "c": "#!/bin/bash\n\n# Check that environment variables are present\n# DEEPSEEK_API_KEY must be defined in .bashrc or environment\nif [ -z \"$DEEPSEEK_API_KEY\" ]; then\n echo \"Error: DEEPSEEK_API_KEY variable not defined\"\n echo \"Add the following line to your ~/.bashrc:\"\n echo \"export DEEPSEEK_API_KEY=\\\"sk-your-api-key-here\\\"\"\n exit 1\nfi\n\n# Set default model if not specified\nif [ -z \"$DEEPSEEK_MODEL\" ]; then\n DEEPSEEK_MODEL=\"deepseek-chat\"\nfi\n\nis_bash_script() {\n [[ \"$1\" =~ ^#!\\/bin\\/bash ]] && return 0 || return 1\n}\n\n# MCP function to get available tools\nget_mcp_tools() {\n if [ \"$MCP_ENABLED\" = \"true\" ]; then\n local mcp_request='{\"method\": \"tools/list\", \"params\": {}}'\n # Enable web search if -w option is used\n if [ \"$WEB_SEARCH\" = \"true\" ]; then\n export MCP_WEB_SEARCH=true\n fi\n \n # Determine MCP tools directory\n local mcp_lib_dir=\"/usr/local/lib/deepseek_bash\"\n if [ \"$INSTALL_LOCAL\" = \"true\" ] || [ ! -d \"$mcp_lib_dir\" ]; then\n mcp_lib_dir=\"$HOME/.local/lib/deepseek_bash\"\n fi\n \n # Use the full server if available\n local mcp_server=\"$mcp_lib_dir/mcp_server.py\"\n if [ -f \"$mcp_lib_dir/mcp_server_full.py\" ]; then\n mcp_server=\"$mcp_lib_dir/mcp_server_full.py\"\n elif [ -f \"$mcp_lib_dir/mcp_server_extended.py\" ]; then\n mcp_server=\"$mcp_lib_dir/mcp_server_extended.py\"\n elif [ -f \"./mcp_server_full.py\" ]; then\n mcp_server=\"./mcp_server_full.py\"\n elif [ -f \"./mcp_server_extended.py\" ]; then\n mcp_server=\"./mcp_server_extended.py\"\n elif [ -f \"./mcp_server.py\" ]; then\n mcp_server=\"./mcp_server.py\"\n fi\n \n local mcp_result=$(echo \"$mcp_request\" | python3 \"$mcp_server\" \"$PWD\" 2>/dev/null)\n if [ $? -eq 0 ] && [ -n \"$mcp_result\" ]; then\n echo \"$mcp_result\" | python3 -c \"import sys, json; r=json.load(sys.stdin); print('\\n'.join([f'- {t[\\\"name\\\"]}: {t[\\\"description\\\"]}' for t in r.get('tools', [])])) if 'tools' in r else print('No MCP tools available')\"\n fi\n fi\n}\n\n# Display help if no arguments provided or if --help is used\nif [ $# -eq 0 ] || [[ \"$1\" == \"--help\" ]] || [[ \"$1\" == \"-h\" ]]; then\n echo -e \"\\033[1;34m\\nUsage:\\033[0m ./dp [options] <question>\"\n echo -e \"\\033[1;34m\\nOptions:\\033[0m\"\n echo -e \" \\033[1;32m-h, --help\\033[0m Display this help\"\n echo -e \" \\033[1;32m-c, --confirmation\\033[0m Ask for confirmation before executing command\"\n echo -e \" \\033[1;32m-d, --debug\\033[0m Display debug information (question, JSON, response)\"\n echo -e \" \\033[1;32m-s, --save <file>\\033[0m Save output to a file\"\n echo -e \" \\033[1;32m-p, --push <file>\\033[0m Include file content in the question (can be used multiple times)\"\n echo -e \" \\033[1;32m-m, --enable-mcp\\033[0m Enable MCP file access tools (disabled by default)\"\n echo -e \" \\033[1;32m-w, --web-search\\033[0m Enable MCP web search tools\"\n echo -e \"\\033[1;34m\\nBasic examples:\\033[0m\"\n echo -e \" ./dp create a new Python file with hello world\"\n echo -e \" ./dp -c list files in color\"\n echo -e \" ./dp -d show disk usage\"\n echo -e \" ./dp -p README.MD summarize in one sentence in Dutch\"\n echo -e \" ./dp -m list files using MCP tools (enable MCP)\"\n echo -e \" ./dp -s output.txt list all files in current directory\"\n \n echo -e \"\\033[1;34m\\nExamples with MCP tools:\\033[0m\"\n echo -e \" \\033[1;36mDocker:\\033[0m\"\n echo -e \" ./dp show me my Docker containers\"\n echo -e \" ./dp display logs of nginx container\"\n echo -e \" ./dp restart all Docker Compose services\"\n \n echo -e \" \\033[1;36mMemory/Cache:\\033[0m\"\n echo -e \" ./dp remember that my API token is abc123\"\n echo -e \" ./dp what have I stored in memory\"\n echo -e \" ./dp delete the token from memory\"\n \n echo -e \" \\033[1;36mWeb Requests:\\033[0m\"\n echo -e \" ./dp fetch the GitHub API and show the result\"\n echo -e \" ./dp -w search for latest Python news\"\n echo -e \" ./dp download multiple URLs in parallel\"\n \n echo -e \" \\033[1;36mSystem:\\033[0m\"\n echo -e \" ./dp analyze disk usage and show largest folders\"\n echo -e \" ./dp monitor running Python processes\"\n echo -e \" ./dp analyze system logs for errors\"\n \n # Display available MCP tools if enabled\n if [ \"$MCP_ENABLED\" = \"true\" ]; then\n echo -e \"\\033[1;34m\\nAvailable MCP tools:\\033[0m\"\n get_mcp_tools\n fi\n \n exit 0\nfi\n\nCONFIRM=false\nDEBUG=false\nSAVE=false\nSAVE_PATH=\"\"\nPUSH_FILES=()\nMCP_ENABLED=false\nWEB_SEARCH=false\nwhile [[ \"$1\" =~ ^- ]]; do\n case \"$1\" in\n -c|--confirmation)\n CONFIRM=true\n shift\n ;;\n -d|--debug)\n DEBUG=true\n shift\n ;;\n -s|--save)\n SAVE=true\n SAVE_PATH=\"$2\"\n shift 2\n ;;\n -p|--push)\n PUSH_FILES+=(\"$2\")\n shift 2\n ;;\n -m|--enable-mcp)\n MCP_ENABLED=true\n shift\n ;;\n -w|--web-search)\n WEB_SEARCH=true\n shift\n ;;\n *)\n break\n ;;\n esac\ndone\n\n# Retrieve and escape the last HISTORY bash commands\nHIST_COUNT=${HISTORY:-10}\nBASH_HISTORY_RAW=$(tail -n \"$HIST_COUNT\" ~/.bash_history | awk '{print NR \": \" $0}')\nBASH_HISTORY=$(printf '%s' \"$BASH_HISTORY_RAW\" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read())[1:-1])')\n\n# Add push file contents to the question\nPUSH_CONTENT=\"\"\nfor f in \"${PUSH_FILES[@]}\"; do\n if [ -f \"$f\" ]; then\n FILE_TEXT=$(cat \"$f\")\n PUSH_CONTENT+=\"\\n\\n--- File: $f ---\\n$FILE_TEXT\"\n else\n PUSH_CONTENT+=\"\\n\\n--- File: $f not found ---\"\n fi\ndone\n\n# Build the request from arguments\nPROMPT=\"$*\"\nif [ -n \"$PUSH_CONTENT\" ]; then\n PROMPT=\"$PUSH_CONTENT\\n\\n$PROMPT\"\nfi\n\n# Get project RAG context (temporarily disabled - causes blocking)\nRAG_CONTEXT=\"\"\n\n# Get MCP tools if enabled (use extended server if available)\nMCP_TOOLS_INFO=\"\"\nif [ \"$MCP_ENABLED\" = \"true\" ]; then\n MCP_REQUEST='{\"method\": \"tools/list\", \"params\": {}}'\n # Enable web search if -w option is used\n if [ \"$WEB_SEARCH\" = \"true\" ]; then\n export MCP_WEB_SEARCH=true\n fi\n \n# Determine dp script directory\n SCRIPT_DIR=\"$(dirname \"$(readlink -f \"$0\")\")\"\n \n # Define system MCP tools directory\n MCP_LIB_DIR=\"/usr/local/lib/deepseek_bash\"\n if [ \"$INSTALL_LOCAL\" = \"true\" ] || [ ! -d \"$MCP_LIB_DIR\" ]; then\n MCP_LIB_DIR=\"$HOME/.local/lib/deepseek_bash\"\n fi\n \n # Use full server if available, otherwise extended, otherwise original\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server.py\"\n if [ -f \"$MCP_LIB_DIR/mcp_server_full.py\" ]; then\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server_full.py\"\n elif [ -f \"$MCP_LIB_DIR/mcp_server_extended.py\" ]; then\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server_extended.py\"\n elif [ -f \"./mcp_server_full.py\" ]; then\n # Fallback to current directory if system tools not found\n MCP_SERVER=\"./mcp_server_full.py\"\n elif [ -f \"./mcp_server_extended.py\" ]; then\n MCP_SERVER=\"./mcp_server_extended.py\"\n elif [ -f \"./mcp_server.py\" ]; then\n MCP_SERVER=\"./mcp_server.py\"\n fi\n \n MCP_RESULT=$(echo \"$MCP_REQUEST\" | python3 \"$MCP_SERVER\" \"$PWD\" 2>/dev/null)\n if [ $? -eq 0 ] && [ -n \"$MCP_RESULT\" ]; then\n MCP_TOOLS_INFO=$(echo \"$MCP_RESULT\" | python3 -c \"\nimport sys, json\nr = json.load(sys.stdin)\nif 'tools' in r:\n tools_desc = '\\\\n\\\\nAVAILABLE TOOLS VIA MCP:\\\\n'\n # Categorize tools\n categories = {\n 'Files': ['read_file', 'write_file', 'list_files', 'file_info'],\n 'Development': ['git_status', 'run_tests', 'analyze_dependencies'],\n 'System': ['json_query', 'process_monitor', 'log_analyzer', 'network_scan', 'disk_analyzer'],\n 'Documentation': ['generate_readme', 'extract_api_docs'],\n 'Web': ['web_search', 'fetch_url', 'fetch_advanced', 'fetch_batch'],\n 'Docker': ['docker_status', 'docker_logs', 'docker_exec', 'docker_compose'],\n 'Email': ['send_email', 'read_latest_emails', 'read_emails'],\n 'Memory': ['memory_store', 'memory_get', 'memory_list', 'memory_delete'],\n 'Puppeteer': ['puppeteer_screenshot', 'puppeteer_scrape', 'puppeteer_pdf'],\n 'PDF': ['read_pdf', 'pdf_info']\n }\n \n tools_by_category = {}\n for tool in r['tools']:\n for cat, tool_names in categories.items():\n if tool['name'] in tool_names:\n if cat not in tools_by_category:\n tools_by_category[cat] = []\n tools_by_category[cat].append(tool)\n break\n \n for category, tools in tools_by_category.items():\n tools_desc += f'\\\\n{category}:\\\\n'\n for tool in tools:\n tools_desc += f'- {tool[\\\"name\\\"]}: {tool[\\\"description\\\"]}\\\\n'\n \n tools_desc += '\\\\nTo use an MCP tool, respond with a function call in format:\\\\n'\n tools_desc += 'MCP_CALL:{\\\"tool\\\": \\\"tool_name\\\", \\\"args\\\": {\\\"param1\\\": \\\"value1\\\"}}\\\\n'\n print(tools_desc)\nelse:\n print('')\n\")\n fi\nfi\n\n# Build messages while avoiding JSON escaping issues\nif [ \"$MCP_ENABLED\" = \"true\" ] && [ -n \"$MCP_TOOLS_INFO\" ]; then\n SYSTEM_MESSAGE=\"You are a helpful assistant with access to advanced development, system and documentation tools via MCP. IMPORTANT: You must respond with ONLY one of these two formats, nothing else:\n\n1) A bash command starting with #!/bin/bash\nExample: #!/bin/bash\nls -la\n\n2) An MCP tool call in the exact format: MCP_CALL:{\\\"tool\\\": \\\"tool_name\\\", \\\"args\\\": {}}\nExamples:\nMCP_CALL:{\\\"tool\\\": \\\"list_files\\\", \\\"args\\\": {\\\"path\\\": \\\".\\\"}} \nMCP_CALL:{\\\"tool\\\": \\\"docker_status\\\", \\\"args\\\": {}} \nMCP_CALL:{\\\"tool\\\": \\\"memory_store\\\", \\\"args\\\": {\\\"key\\\": \\\"test\\\", \\\"value\\\": \\\"data\\\"}} \nMCP_CALL:{\\\"tool\\\": \\\"git_status\\\", \\\"args\\\": {}}\n\nIMPORTANT EMAIL USAGE:\n- For reading/checking emails, ALWAYS use 'read_latest_emails' tool (it handles credentials automatically)\n- Example: MCP_CALL:{\\\"tool\\\": \\\"read_latest_emails\\\", \\\"args\\\": {\\\"limit\\\": 3}}\n- Do NOT use 'read_emails' tool unless user specifically provides email credentials\n\nDo NOT add any explanatory text, comments, or additional content. Use ONLY the tools listed below:\n$MCP_TOOLS_INFO\"\nelse\n SYSTEM_MESSAGE=\"You are a helpful assistant. You only answer with a bash command, no explanation. If you return a command, always start with #!/bin/bash. MCP tools are disabled - use only standard bash commands.\"\nfi\n\n# Use a temporary file to build JSON properly\nTEMP_FILE=$(mktemp)\ncat > \"$TEMP_FILE\" << EOF\n{\n \"model\": \"$DEEPSEEK_MODEL\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": $(echo \"$SYSTEM_MESSAGE\" | python3 -c \"import json, sys; print(json.dumps(sys.stdin.read().strip()))\")\n },\n {\n \"role\": \"user\", \n \"content\": $(printf \"Previous command history: %s%s\\n\\nQuestion: %s\" \"$BASH_HISTORY_RAW\" \"$RAG_CONTEXT\" \"$PROMPT\" | python3 -c \"import json, sys; print(json.dumps(sys.stdin.read().strip()))\")\n }\n ],\n \"stream\": false\n}\nEOF\nJSON_PAYLOAD=$(cat \"$TEMP_FILE\")\nrm -f \"$TEMP_FILE\"\n\nRESPONSE=$(curl -s -X POST \"https://api.deepseek.com/chat/completions\" \\\n -H \"Authorization: Bearer $DEEPSEEK_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -H \"HTTP-Referer: https://github.com/michael/deepseek_bash\" \\\n -H \"X-Title: DeepSeek-Bash\" \\\n -d \"$JSON_PAYLOAD\")\n\n# Extract the generated command (assistant field, nested JSON)\nCOMMAND=$(echo \"$RESPONSE\" | python3 -c \"import sys, json; r=json.load(sys.stdin); print(r['choices'][0]['message']['content']) if 'choices' in r and r['choices'] else print('')\")\n\nif [ -z \"$COMMAND\" ]; then\n ERROR_MSG=$(echo \"$RESPONSE\" | grep -oP '\"error_msg\"\\s*:\\s*\"\\K[^\"}]+')\n if [ -n \"$ERROR_MSG\" ]; then\n echo \"DeepSeek API Error: $ERROR_MSG\"\n else\n echo \"Error: no command generated. Response: $RESPONSE\"\n fi\n exit 2\nfi\n\n# Function to execute an MCP call\nexecute_mcp_call() {\n local mcp_call=\"$1\"\n local tool_call=$(echo \"$mcp_call\" | sed 's/^MCP_CALL://')\n \n # Parse JSON in one go to avoid double reading errors\n local tool_info=$(echo \"$tool_call\" | python3 -c \"\nimport sys, json\nr = json.loads(sys.stdin.read())\nprint(r.get('tool', ''), '|||', json.dumps(r.get('args', {})))\n\")\n \n local tool_name=$(echo \"$tool_info\" | cut -d'|' -f1 | xargs)\n local tool_args=$(echo \"$tool_info\" | cut -d'|' -f4- | sed 's/^[[:space:]]*//')\n \n local mcp_request='{\"method\": \"tools/call\", \"params\": {\"name\": \"'$tool_name'\", \"arguments\": '$tool_args'}}'\n \n # Enable web search if -w option is used\n if [ \"$WEB_SEARCH\" = \"true\" ]; then\n export MCP_WEB_SEARCH=true\n fi\n \n # Define system MCP tools directory\n MCP_LIB_DIR=\"/usr/local/lib/deepseek_bash\"\n if [ \"$INSTALL_LOCAL\" = \"true\" ] || [ ! -d \"$MCP_LIB_DIR\" ]; then\n MCP_LIB_DIR=\"$HOME/.local/lib/deepseek_bash\"\n fi\n \n # Use full server if available\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server.py\"\n if [ -f \"$MCP_LIB_DIR/mcp_server_full.py\" ]; then\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server_full.py\"\n elif [ -f \"$MCP_LIB_DIR/mcp_server_extended.py\" ]; then\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server_extended.py\"\n elif [ -f \"./mcp_server_full.py\" ]; then\n # Fallback to current directory if system tools not found\n MCP_SERVER=\"./mcp_server_full.py\"\n elif [ -f \"./mcp_server_extended.py\" ]; then\n MCP_SERVER=\"./mcp_server_extended.py\"\n elif [ -f \"./mcp_server.py\" ]; then\n MCP_SERVER=\"./mcp_server.py\"\n fi\n \n echo \"$mcp_request\" | python3 \"$MCP_SERVER\" \"$PWD\"\n}\n\n# Display command before execution or debug\necho \"----------------------------------------\"\nif [[ \"$COMMAND\" =~ ^MCP_CALL: ]]; then\n # This is an MCP call\n echo -e \"\\033[1;33mExecuting an MCP call...\\033[0m\"\n # Extract only the MCP_CALL part\n MCP_LINE=$(echo \"$COMMAND\" | grep -o 'MCP_CALL:.*')\n MCP_RESULT=$(execute_mcp_call \"$MCP_LINE\")\n # Process MCP result with intelligent formatting\n FORMAT_SCRIPT=\"$MCP_LIB_DIR/format_mcp_output.py\"\n if [ ! -f \"$FORMAT_SCRIPT\" ]; then\n FORMAT_SCRIPT=\"./format_mcp_output.py\" # Fallback\n fi\n echo \"$MCP_RESULT\" | python3 \"$FORMAT_SCRIPT\"\nelif is_bash_script \"$COMMAND\"; then\n # Remove shebang and empty lines\n CMD_MAIN=$(echo \"$COMMAND\" | sed '1{/^#!\\/bin\\/bash$/d}' | sed '/^$/d' | tail -n 1)\n bash -c \"$CMD_MAIN\" 2>&1\nelse\n echo \"$COMMAND\"\nfi\nif [ \"$DEBUG\" = true ]; then\n echo -e \"\\n--- DEBUG ---\"\n echo -e \"\\033[1;34mQuestion sent to DeepSeek:\\033[0m\"\n echo -e \"\\033[1;34mPrevious command history:\\033[0m\"\n tail -n \"${HISTORY:-10}\" ~/.bash_history | awk '{print NR \": \" $0}'\n echo -e \"\\n\\033[1;34mQuestion:\\033[0m $*\"\n echo -e \"\\n\\033[1;34mJSON sent:\\033[0m\"\n echo \"$JSON_PAYLOAD\"\n echo -e \"\\n\\033[1;34mDeepSeek JSON response:\\033[0m\"\n echo \"$RESPONSE\"\n echo -e \"\\n\\033[1;32mCommand proposed by DeepSeek:\\033[0m\"\n echo \"$COMMAND\"\n echo \"--- END DEBUG ---\"\n exit 0\nfi\nif [ \"$SAVE\" = true ]; then\n if [ -z \"$SAVE_PATH\" ]; then\n echo \"Error: missing file path for -s/--save option.\"\n exit 3\n fi\n bash -c \"$COMMAND\" > \"$SAVE_PATH\"\n echo \"Command result saved to: $SAVE_PATH\"\n exit 0\nfi\n\n# Function to detect dangerous commands\nis_dangerous_command() {\n local cmd=\"$1\"\n # Potentially dangerous commands\n local dangerous_patterns=(\n \"rm -rf\"\n \"rm.*-rf\"\n \"dd.*if=/dev/zero\"\n \"mkfs\\.\"\n \"fdisk\"\n \"parted\"\n \"fsck.*-y\"\n \"chmod.*777\"\n \"chown.*-R.*root\"\n \"sudo.*rm\"\n \"sudo.*chmod\"\n \"sudo.*chown\"\n \"sudo.*dd\"\n \"wget.*|.*sh\"\n \"curl.*|.*sh\"\n \"curl.*|.*bash\"\n \"wget.*|.*bash\"\n \">/etc/\"\n \"echo.*>.*passwd\"\n \"echo.*>.*shadow\"\n \"docker.*--privileged\"\n \"docker.*-v.*:/\"\n \"systemctl.*stop\"\n \"systemctl.*disable\"\n \"service.*stop\"\n \"pkill.*-9\"\n \"killall.*-9\"\n \"shutdown\"\n \"reboot\"\n \"halt\"\n \"poweroff\"\n \"init 0\"\n \"init 6\"\n )\n \n for pattern in \"${dangerous_patterns[@]}\"; do\n if [[ \"$cmd\" =~ $pattern ]]; then\n return 0\n fi\n done\n return 1\n}\n\n# Function to display a command in a readable way\ndisplay_command() {\n local cmd=\"$1\"\n local cmd_type=\"$2\"\n \n echo -e \"\\033[1;36m=== COMMAND TO EXECUTE ===\\033[0m\"\n if [ \"$cmd_type\" = \"mcp\" ]; then\n echo -e \"\\033[1;33mType:\\033[0m MCP call\"\n local mcp_call=$(echo \"$cmd\" | grep -o 'MCP_CALL:.*')\n local tool_info=$(echo \"$mcp_call\" | sed 's/^MCP_CALL://' | python3 -c \"\ntry:\n import sys, json\n r = json.loads(sys.stdin.read())\n print(f\\\"Tool: {r.get('tool', 'unknown')}\\\")\n print(f\\\"Arguments: {json.dumps(r.get('args', {}), indent=2)}\\\")\nexcept:\n print('Invalid MCP format')\n\")\n echo -e \"\\033[1;32m$tool_info\\033[0m\"\n elif [ \"$cmd_type\" = \"bash\" ]; then\n echo -e \"\\033[1;33mType:\\033[0m Bash command\"\n local cmd_clean=$(echo \"$cmd\" | sed '1{/^#!\\/bin\\/bash$/d}' | sed '/^$/d')\n echo -e \"\\033[1;32m$cmd_clean\\033[0m\"\n else\n echo -e \"\\033[1;33mType:\\033[0m Text response\"\n echo -e \"\\033[1;32m$cmd\\033[0m\"\n fi\n echo -e \"\\033[1;36m========================\\033[0m\"\n}\n\n# Function to ask for confirmation\nask_confirmation() {\n local prompt=\"$1\"\n echo -e \"\\033[1;31m$prompt\\033[0m\"\n echo -e \"\\033[1;33mDo you want to continue? [y/N]\\033[0m\"\n read -r response\n case \"$response\" in\n [yY]|[yY][eE][sS]|[oO]|[oO][uU][iI])\n return 0\n ;;\n *)\n echo -e \"\\033[1;31mCancelled by user\\033[0m\"\n return 1\n ;;\n esac\n}\n\n# Main execution logic with display and confirmation\nif [[ \"$COMMAND\" =~ ^MCP_CALL: ]]; then\n # This is an MCP call\n display_command \"$COMMAND\" \"mcp\"\n \n if [ \"$CONFIRM\" = true ]; then\n if ! ask_confirmation \"⚠️ Confirm execution of this MCP call?\"; then\n exit 1\n fi\n fi\n \n echo -e \"\\033[1;33mExecuting an MCP call...\\033[0m\"\n # Extract only the MCP_CALL part\n MCP_LINE=$(echo \"$COMMAND\" | grep -o 'MCP_CALL:.*')\n MCP_RESULT=$(execute_mcp_call \"$MCP_LINE\")\n # Process MCP result with intelligent formatting\n FORMAT_SCRIPT=\"$MCP_LIB_DIR/format_mcp_output.py\"\n if [ ! -f \"$FORMAT_SCRIPT\" ]; then\n FORMAT_SCRIPT=\"./format_mcp_output.py\" # Fallback\n fi\n if [ -f \"$FORMAT_SCRIPT\" ]; then\n echo \"$MCP_RESULT\" | python3 \"$FORMAT_SCRIPT\"\n else\n echo \"$MCP_RESULT\"\n fi\n \nelif is_bash_script \"$COMMAND\"; then\n # This is a bash command\n CMD_MAIN=$(echo \"$COMMAND\" | sed '1{/^#!\\/bin\\/bash$/d}' | sed '/^$/d' | tail -n 1)\n \n display_command \"$COMMAND\" \"bash\"\n \n # Check if it's a dangerous command\n if is_dangerous_command \"$CMD_MAIN\"; then\n if ! ask_confirmation \"⚠️ WARNING: This command is potentially dangerous!\"; then\n exit 1\n fi\n elif [ \"$CONFIRM\" = true ]; then\n if ! ask_confirmation \"Confirm execution of this command?\"; then\n exit 1\n fi\n fi\n \n echo -e \"\\033[1;32mExecuting...\\033[0m\"\n bash -c \"$CMD_MAIN\" 2>&1\n \nelse\n # Text response\n display_command \"$COMMAND\" \"text\"\n if [ \"$CONFIRM\" = true ]; then\n if ! ask_confirmation \"Does this response contain sensitive information?\"; then\n exit 1\n fi\n fi\nfi\n"}, "c86158787d69afcad2645d232c59a7bf293fe658": {"t": 1785765264.8724017, "n": 18522, "h": "adcbf584c76e643f", "c": "#!/bin/bash\n\n# Check that environment variables are present\n# DEEPSEEK_API_KEY must be defined in .bashrc or environment\nif [ -z \"$DEEPSEEK_API_KEY\" ]; then\n echo \"Error: DEEPSEEK_API_KEY variable not defined\"\n echo \"Add the following line to your ~/.bashrc:\"\n echo \"export DEEPSEEK_API_KEY=\\\"sk-your-api-key-here\\\"\"\n exit 1\nfi\n\n# Set default model if not specified\nif [ -z \"$DEEPSEEK_MODEL\" ]; then\n DEEPSEEK_MODEL=\"deepseek-chat\"\nfi\n\nis_bash_script() {\n [[ \"$1\" =~ ^#!\\/bin\\/bash ]] && return 0 || return 1\n}\n\n# MCP function to get available tools\nget_mcp_tools() {\n if [ \"$MCP_ENABLED\" = \"true\" ]; then\n local mcp_request='{\"method\": \"tools/list\", \"params\": {}}'\n # Enable web search if -w option is used\n if [ \"$WEB_SEARCH\" = \"true\" ]; then\n export MCP_WEB_SEARCH=true\n fi\n \n # Determine MCP tools directory\n local mcp_lib_dir=\"/usr/local/lib/deepseek_bash\"\n if [ \"$INSTALL_LOCAL\" = \"true\" ] || [ ! -d \"$mcp_lib_dir\" ]; then\n mcp_lib_dir=\"$HOME/.local/lib/deepseek_bash\"\n fi\n \n # Use the full server if available\n local mcp_server=\"$mcp_lib_dir/mcp_server.py\"\n if [ -f \"$mcp_lib_dir/mcp_server_full.py\" ]; then\n mcp_server=\"$mcp_lib_dir/mcp_server_full.py\"\n elif [ -f \"$mcp_lib_dir/mcp_server_extended.py\" ]; then\n mcp_server=\"$mcp_lib_dir/mcp_server_extended.py\"\n elif [ -f \"./mcp_server_full.py\" ]; then\n mcp_server=\"./mcp_server_full.py\"\n elif [ -f \"./mcp_server_extended.py\" ]; then\n mcp_server=\"./mcp_server_extended.py\"\n elif [ -f \"./mcp_server.py\" ]; then\n mcp_server=\"./mcp_server.py\"\n fi\n \n local mcp_result=$(echo \"$mcp_request\" | python3 \"$mcp_server\" \"$PWD\" 2>/dev/null)\n if [ $? -eq 0 ] && [ -n \"$mcp_result\" ]; then\n echo \"$mcp_result\" | python3 -c \"import sys, json; r=json.load(sys.stdin); print('\\n'.join([f'- {t[\\\"name\\\"]}: {t[\\\"description\\\"]}' for t in r.get('tools', [])])) if 'tools' in r else print('No MCP tools available')\"\n fi\n fi\n}\n\n# Display help if no arguments provided or if --help is used\nif [ $# -eq 0 ] || [[ \"$1\" == \"--help\" ]] || [[ \"$1\" == \"-h\" ]]; then\n echo -e \"\\033[1;34m\\nUsage:\\033[0m ./dp [options] <question>\"\n echo -e \"\\033[1;34m\\nOptions:\\033[0m\"\n echo -e \" \\033[1;32m-h, --help\\033[0m Display this help\"\n echo -e \" \\033[1;32m-c, --confirmation\\033[0m Ask for confirmation before executing command\"\n echo -e \" \\033[1;32m-d, --debug\\033[0m Display debug information (question, JSON, response)\"\n echo -e \" \\033[1;32m-s, --save <file>\\033[0m Save output to a file\"\n echo -e \" \\033[1;32m-p, --push <file>\\033[0m Include file content in the question (can be used multiple times)\"\n echo -e \" \\033[1;32m-m, --enable-mcp\\033[0m Enable MCP file access tools (disabled by default)\"\n echo -e \" \\033[1;32m-w, --web-search\\033[0m Enable MCP web search tools\"\n echo -e \"\\033[1;34m\\nBasic examples:\\033[0m\"\n echo -e \" ./dp create a new Python file with hello world\"\n echo -e \" ./dp -c list files in color\"\n echo -e \" ./dp -d show disk usage\"\n echo -e \" ./dp -p README.MD summarize in one sentence in Dutch\"\n echo -e \" ./dp -m list files using MCP tools (enable MCP)\"\n echo -e \" ./dp -s output.txt list all files in current directory\"\n \n echo -e \"\\033[1;34m\\nExamples with MCP tools:\\033[0m\"\n echo -e \" \\033[1;36mDocker:\\033[0m\"\n echo -e \" ./dp show me my Docker containers\"\n echo -e \" ./dp display logs of nginx container\"\n echo -e \" ./dp restart all Docker Compose services\"\n \n echo -e \" \\033[1;36mMemory/Cache:\\033[0m\"\n echo -e \" ./dp remember that my API token is abc123\"\n echo -e \" ./dp what have I stored in memory\"\n echo -e \" ./dp delete the token from memory\"\n \n echo -e \" \\033[1;36mWeb Requests:\\033[0m\"\n echo -e \" ./dp fetch the GitHub API and show the result\"\n echo -e \" ./dp -w search for latest Python news\"\n echo -e \" ./dp download multiple URLs in parallel\"\n \n echo -e \" \\033[1;36mSystem:\\033[0m\"\n echo -e \" ./dp analyze disk usage and show largest folders\"\n echo -e \" ./dp monitor running Python processes\"\n echo -e \" ./dp analyze system logs for errors\"\n \n # Display available MCP tools if enabled\n if [ \"$MCP_ENABLED\" = \"true\" ]; then\n echo -e \"\\033[1;34m\\nAvailable MCP tools:\\033[0m\"\n get_mcp_tools\n fi\n \n exit 0\nfi\n\nCONFIRM=false\nDEBUG=false\nSAVE=false\nSAVE_PATH=\"\"\nPUSH_FILES=()\nMCP_ENABLED=false\nWEB_SEARCH=false\nwhile [[ \"$1\" =~ ^- ]]; do\n case \"$1\" in\n -c|--confirmation)\n CONFIRM=true\n shift\n ;;\n -d|--debug)\n DEBUG=true\n shift\n ;;\n -s|--save)\n SAVE=true\n SAVE_PATH=\"$2\"\n shift 2\n ;;\n -p|--push)\n PUSH_FILES+=(\"$2\")\n shift 2\n ;;\n -m|--enable-mcp)\n MCP_ENABLED=true\n shift\n ;;\n -w|--web-search)\n WEB_SEARCH=true\n shift\n ;;\n *)\n break\n ;;\n esac\ndone\n\n# Retrieve and escape the last HISTORY bash commands\nHIST_COUNT=${HISTORY:-10}\nBASH_HISTORY_RAW=$(tail -n \"$HIST_COUNT\" ~/.bash_history | awk '{print NR \": \" $0}')\nBASH_HISTORY=$(printf '%s' \"$BASH_HISTORY_RAW\" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read())[1:-1])')\n\n# Add push file contents to the question\nPUSH_CONTENT=\"\"\nfor f in \"${PUSH_FILES[@]}\"; do\n if [ -f \"$f\" ]; then\n FILE_TEXT=$(cat \"$f\")\n PUSH_CONTENT+=\"\\n\\n--- File: $f ---\\n$FILE_TEXT\"\n else\n PUSH_CONTENT+=\"\\n\\n--- File: $f not found ---\"\n fi\ndone\n\n# Build the request from arguments\nPROMPT=\"$*\"\nif [ -n \"$PUSH_CONTENT\" ]; then\n PROMPT=\"$PUSH_CONTENT\\n\\n$PROMPT\"\nfi\n\n# Get project RAG context (temporarily disabled - causes blocking)\nRAG_CONTEXT=\"\"\n\n# Get MCP tools if enabled (use extended server if available)\nMCP_TOOLS_INFO=\"\"\nif [ \"$MCP_ENABLED\" = \"true\" ]; then\n MCP_REQUEST='{\"method\": \"tools/list\", \"params\": {}}'\n # Enable web search if -w option is used\n if [ \"$WEB_SEARCH\" = \"true\" ]; then\n export MCP_WEB_SEARCH=true\n fi\n \n# Determine dp script directory\n SCRIPT_DIR=\"$(dirname \"$(readlink -f \"$0\")\")\"\n \n # Define system MCP tools directory\n MCP_LIB_DIR=\"/usr/local/lib/deepseek_bash\"\n if [ \"$INSTALL_LOCAL\" = \"true\" ] || [ ! -d \"$MCP_LIB_DIR\" ]; then\n MCP_LIB_DIR=\"$HOME/.local/lib/deepseek_bash\"\n fi\n \n # Use full server if available, otherwise extended, otherwise original\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server.py\"\n if [ -f \"$MCP_LIB_DIR/mcp_server_full.py\" ]; then\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server_full.py\"\n elif [ -f \"$MCP_LIB_DIR/mcp_server_extended.py\" ]; then\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server_extended.py\"\n elif [ -f \"./mcp_server_full.py\" ]; then\n # Fallback to current directory if system tools not found\n MCP_SERVER=\"./mcp_server_full.py\"\n elif [ -f \"./mcp_server_extended.py\" ]; then\n MCP_SERVER=\"./mcp_server_extended.py\"\n elif [ -f \"./mcp_server.py\" ]; then\n MCP_SERVER=\"./mcp_server.py\"\n fi\n \n MCP_RESULT=$(echo \"$MCP_REQUEST\" | python3 \"$MCP_SERVER\" \"$PWD\" 2>/dev/null)\n if [ $? -eq 0 ] && [ -n \"$MCP_RESULT\" ]; then\n MCP_TOOLS_INFO=$(echo \"$MCP_RESULT\" | python3 -c \"\nimport sys, json\nr = json.load(sys.stdin)\nif 'tools' in r:\n tools_desc = '\\\\n\\\\nAVAILABLE TOOLS VIA MCP:\\\\n'\n # Categorize tools\n categories = {\n 'Files': ['read_file', 'write_file', 'list_files', 'file_info'],\n 'Development': ['git_status', 'run_tests', 'analyze_dependencies'],\n 'System': ['json_query', 'process_monitor', 'log_analyzer', 'network_scan', 'disk_analyzer'],\n 'Documentation': ['generate_readme', 'extract_api_docs'],\n 'Web': ['web_search', 'fetch_url', 'fetch_advanced', 'fetch_batch'],\n 'Docker': ['docker_status', 'docker_logs', 'docker_exec', 'docker_compose'],\n 'Email': ['send_email', 'read_latest_emails', 'read_emails'],\n 'Memory': ['memory_store', 'memory_get', 'memory_list', 'memory_delete'],\n 'Puppeteer': ['puppeteer_screenshot', 'puppeteer_scrape', 'puppeteer_pdf'],\n 'PDF': ['read_pdf', 'pdf_info']\n }\n \n tools_by_category = {}\n for tool in r['tools']:\n for cat, tool_names in categories.items():\n if tool['name'] in tool_names:\n if cat not in tools_by_category:\n tools_by_category[cat] = []\n tools_by_category[cat].append(tool)\n break\n \n for category, tools in tools_by_category.items():\n tools_desc += f'\\\\n{category}:\\\\n'\n for tool in tools:\n tools_desc += f'- {tool[\\\"name\\\"]}: {tool[\\\"description\\\"]}\\\\n'\n \n tools_desc += '\\\\nTo use an MCP tool, respond with a function call in format:\\\\n'\n tools_desc += 'MCP_CALL:{\\\"tool\\\": \\\"tool_name\\\", \\\"args\\\": {\\\"param1\\\": \\\"value1\\\"}}\\\\n'\n print(tools_desc)\nelse:\n print('')\n\")\n fi\nfi\n\n# Build messages while avoiding JSON escaping issues\nif [ \"$MCP_ENABLED\" = \"true\" ] && [ -n \"$MCP_TOOLS_INFO\" ]; then\n SYSTEM_MESSAGE=\"You are a helpful assistant with access to advanced development, system and documentation tools via MCP. IMPORTANT: You must respond with ONLY one of these two formats, nothing else:\n\n1) A bash command starting with #!/bin/bash\nExample: #!/bin/bash\nls -la\n\n2) An MCP tool call in the exact format: MCP_CALL:{\\\"tool\\\": \\\"tool_name\\\", \\\"args\\\": {}}\nExamples:\nMCP_CALL:{\\\"tool\\\": \\\"list_files\\\", \\\"args\\\": {\\\"path\\\": \\\".\\\"}} \nMCP_CALL:{\\\"tool\\\": \\\"docker_status\\\", \\\"args\\\": {}} \nMCP_CALL:{\\\"tool\\\": \\\"memory_store\\\", \\\"args\\\": {\\\"key\\\": \\\"test\\\", \\\"value\\\": \\\"data\\\"}} \nMCP_CALL:{\\\"tool\\\": \\\"git_status\\\", \\\"args\\\": {}}\n\nIMPORTANT EMAIL USAGE:\n- For reading/checking emails, ALWAYS use 'read_latest_emails' tool (it handles credentials automatically)\n- Example: MCP_CALL:{\\\"tool\\\": \\\"read_latest_emails\\\", \\\"args\\\": {\\\"limit\\\": 3}}\n- Do NOT use 'read_emails' tool unless user specifically provides email credentials\n\nDo NOT add any explanatory text, comments, or additional content. Use ONLY the tools listed below:\n$MCP_TOOLS_INFO\"\nelse\n SYSTEM_MESSAGE=\"You are a helpful assistant. You only answer with a bash command, no explanation. If you return a command, always start with #!/bin/bash. MCP tools are disabled - use only standard bash commands.\"\nfi\n\n# Use a temporary file to build JSON properly\nTEMP_FILE=$(mktemp)\ncat > \"$TEMP_FILE\" << EOF\n{\n \"model\": \"$DEEPSEEK_MODEL\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": $(echo \"$SYSTEM_MESSAGE\" | python3 -c \"import json, sys; print(json.dumps(sys.stdin.read().strip()))\")\n },\n {\n \"role\": \"user\", \n \"content\": $(printf \"Previous command history: %s%s\\n\\nQuestion: %s\" \"$BASH_HISTORY_RAW\" \"$RAG_CONTEXT\" \"$PROMPT\" | python3 -c \"import json, sys; print(json.dumps(sys.stdin.read().strip()))\")\n }\n ],\n \"stream\": false\n}\nEOF\nJSON_PAYLOAD=$(cat \"$TEMP_FILE\")\nrm -f \"$TEMP_FILE\"\n\nRESPONSE=$(curl -s -X POST \"https://api.deepseek.com/chat/completions\" \\\n -H \"Authorization: Bearer $DEEPSEEK_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -H \"HTTP-Referer: https://github.com/michael/deepseek_bash\" \\\n -H \"X-Title: DeepSeek-Bash\" \\\n -d \"$JSON_PAYLOAD\")\n\n# Extract the generated command (assistant field, nested JSON)\nCOMMAND=$(echo \"$RESPONSE\" | python3 -c \"import sys, json; r=json.load(sys.stdin); print(r['choices'][0]['message']['content']) if 'choices' in r and r['choices'] else print('')\")\n\nif [ -z \"$COMMAND\" ]; then\n ERROR_MSG=$(echo \"$RESPONSE\" | grep -oP '\"error_msg\"\\s*:\\s*\"\\K[^\"}]+')\n if [ -n \"$ERROR_MSG\" ]; then\n echo \"DeepSeek API Error: $ERROR_MSG\"\n else\n echo \"Error: no command generated. Response: $RESPONSE\"\n fi\n exit 2\nfi\n\n# Function to execute an MCP call\nexecute_mcp_call() {\n local mcp_call=\"$1\"\n local tool_call=$(echo \"$mcp_call\" | sed 's/^MCP_CALL://')\n \n # Parse JSON in one go to avoid double reading errors\n local tool_info=$(echo \"$tool_call\" | python3 -c \"\nimport sys, json\nr = json.loads(sys.stdin.read())\nprint(r.get('tool', ''), '|||', json.dumps(r.get('args', {})))\n\")\n \n local tool_name=$(echo \"$tool_info\" | cut -d'|' -f1 | xargs)\n local tool_args=$(echo \"$tool_info\" | cut -d'|' -f4- | sed 's/^[[:space:]]*//')\n \n local mcp_request='{\"method\": \"tools/call\", \"params\": {\"name\": \"'$tool_name'\", \"arguments\": '$tool_args'}}'\n \n # Enable web search if -w option is used\n if [ \"$WEB_SEARCH\" = \"true\" ]; then\n export MCP_WEB_SEARCH=true\n fi\n \n # Define system MCP tools directory\n MCP_LIB_DIR=\"/usr/local/lib/deepseek_bash\"\n if [ \"$INSTALL_LOCAL\" = \"true\" ] || [ ! -d \"$MCP_LIB_DIR\" ]; then\n MCP_LIB_DIR=\"$HOME/.local/lib/deepseek_bash\"\n fi\n \n # Use full server if available\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server.py\"\n if [ -f \"$MCP_LIB_DIR/mcp_server_full.py\" ]; then\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server_full.py\"\n elif [ -f \"$MCP_LIB_DIR/mcp_server_extended.py\" ]; then\n MCP_SERVER=\"$MCP_LIB_DIR/mcp_server_extended.py\"\n elif [ -f \"./mcp_server_full.py\" ]; then\n # Fallback to current directory if system tools not found\n MCP_SERVER=\"./mcp_server_full.py\"\n elif [ -f \"./mcp_server_extended.py\" ]; then\n MCP_SERVER=\"./mcp_server_extended.py\"\n elif [ -f \"./mcp_server.py\" ]; then\n MCP_SERVER=\"./mcp_server.py\"\n fi\n \n echo \"$mcp_request\" | python3 \"$MCP_SERVER\" \"$PWD\"\n}\n\n# Display command before execution or debug\necho \"----------------------------------------\"\nif [[ \"$COMMAND\" =~ ^MCP_CALL: ]]; then\n # This is an MCP call\n echo -e \"\\033[1;33mExecuting an MCP call...\\033[0m\"\n # Extract only the MCP_CALL part\n MCP_LINE=$(echo \"$COMMAND\" | grep -o 'MCP_CALL:.*')\n MCP_RESULT=$(execute_mcp_call \"$MCP_LINE\")\n # Process MCP result with intelligent formatting\n FORMAT_SCRIPT=\"$MCP_LIB_DIR/format_mcp_output.py\"\n if [ ! -f \"$FORMAT_SCRIPT\" ]; then\n FORMAT_SCRIPT=\"./format_mcp_output.py\" # Fallback\n fi\n echo \"$MCP_RESULT\" | python3 \"$FORMAT_SCRIPT\"\nelif is_bash_script \"$COMMAND\"; then\n # Remove shebang and empty lines\n CMD_MAIN=$(echo \"$COMMAND\" | sed '1{/^#!\\/bin\\/bash$/d}' | sed '/^$/d' | tail -n 1)\n bash -c \"$CMD_MAIN\" 2>&1\nelse\n echo \"$COMMAND\"\nfi\nif [ \"$DEBUG\" = true ]; then\n echo -e \"\\n--- DEBUG ---\"\n echo -e \"\\033[1;34mQuestion sent to DeepSeek:\\033[0m\"\n echo -e \"\\033[1;34mPrevious command history:\\033[0m\"\n tail -n \"${HISTORY:-10}\" ~/.bash_history | awk '{print NR \": \" $0}'\n echo -e \"\\n\\033[1;34mQuestion:\\033[0m $*\"\n echo -e \"\\n\\033[1;34mJSON sent:\\033[0m\"\n echo \"$JSON_PAYLOAD\"\n echo -e \"\\n\\033[1;34mDeepSeek JSON response:\\033[0m\"\n echo \"$RESPONSE\"\n echo -e \"\\n\\033[1;32mCommand proposed by DeepSeek:\\033[0m\"\n echo \"$COMMAND\"\n echo \"--- END DEBUG ---\"\n exit 0\nfi\nif [ \"$SAVE\" = true ]; then\n if [ -z \"$SAVE_PATH\" ]; then\n echo \"Error: missing file path for -s/--save option.\"\n exit 3\n fi\n bash -c \"$COMMAND\" > \"$SAVE_PATH\"\n echo \"Command result saved to: $SAVE_PATH\"\n exit 0\nfi\n\n# Function to detect dangerous commands\nis_dangerous_command() {\n local cmd=\"$1\"\n # Potentially dangerous commands\n local dangerous_patterns=(\n \"rm -rf\"\n \"rm.*-rf\"\n \"dd.*if=/dev/zero\"\n \"mkfs\\.\"\n \"fdisk\"\n \"parted\"\n \"fsck.*-y\"\n \"chmod.*777\"\n \"chown.*-R.*root\"\n \"sudo.*rm\"\n \"sudo.*chmod\"\n \"sudo.*chown\"\n \"sudo.*dd\"\n \"wget.*|.*sh\"\n \"curl.*|.*sh\"\n \"curl.*|.*bash\"\n \"wget.*|.*bash\"\n \">/etc/\"\n \"echo.*>.*passwd\"\n \"echo.*>.*shadow\"\n \"docker.*--privileged\"\n \"docker.*-v.*:/\"\n \"systemctl.*stop\"\n \"systemctl.*disable\"\n \"service.*stop\"\n \"pkill.*-9\"\n \"killall.*-9\"\n \"shutdown\"\n \"reboot\"\n \"halt\"\n \"poweroff\"\n \"init 0\"\n \"init 6\"\n )\n \n for pattern in \"${dangerous_patterns[@]}\"; do\n if [[ \"$cmd\" =~ $pattern ]]; then\n return 0\n fi\n done\n return 1\n}\n\n# Function to display a command in a readable way\ndisplay_command() {\n local cmd=\"$1\"\n local cmd_type=\"$2\"\n \n echo -e \"\\033[1;36m=== COMMAND TO EXECUTE ===\\033[0m\"\n if [ \"$cmd_type\" = \"mcp\" ]; then\n echo -e \"\\033[1;33mType:\\033[0m MCP call\"\n local mcp_call=$(echo \"$cmd\" | grep -o 'MCP_CALL:.*')\n local tool_info=$(echo \"$mcp_call\" | sed 's/^MCP_CALL://' | python3 -c \"\ntry:\n import sys, json\n r = json.loads(sys.stdin.read())\n print(f\\\"Tool: {r.get('tool', 'unknown')}\\\")\n print(f\\\"Arguments: {json.dumps(r.get('args', {}), indent=2)}\\\")\nexcept:\n print('Invalid MCP format')\n\")\n echo -e \"\\033[1;32m$tool_info\\033[0m\"\n elif [ \"$cmd_type\" = \"bash\" ]; then\n echo -e \"\\033[1;33mType:\\033[0m Bash command\"\n local cmd_clean=$(echo \"$cmd\" | sed '1{/^#!\\/bin\\/bash$/d}' | sed '/^$/d')\n echo -e \"\\033[1;32m$cmd_clean\\033[0m\"\n else\n echo -e \"\\033[1;33mType:\\033[0m Text response\"\n echo -e \"\\033[1;32m$cmd\\033[0m\"\n fi\n echo -e \"\\033[1;36m========================\\033[0m\"\n}\n\n# Function to ask for confirmation\nask_confirmation() {\n local prompt=\"$1\"\n echo -e \"\\033[1;31m$prompt\\033[0m\"\n echo -e \"\\033[1;33mDo you want to continue? [y/N]\\033[0m\"\n read -r response\n case \"$response\" in\n [yY]|[yY][eE][sS]|[oO]|[oO][uU][iI])\n return 0\n ;;\n *)\n echo -e \"\\033[1;31mCancelled by user\\033[0m\"\n return 1\n ;;\n esac\n}\n\n# Main execution logic with display and confirmation\nif [[ \"$COMMAND\" =~ ^MCP_CALL: ]]; then\n # This is an MCP call\n display_command \"$COMMAND\" \"mcp\"\n \n if [ \"$CONFIRM\" = true ]; then\n if ! ask_confirmation \"⚠️ Confirm execution of this MCP call?\"; then\n exit 1\n fi\n fi\n \n echo -e \"\\033[1;33mExecuting an MCP call...\\033[0m\"\n # Extract only the MCP_CALL part\n MCP_LINE=$(echo \"$COMMAND\" | grep -o 'MCP_CALL:.*')\n MCP_RESULT=$(execute_mcp_call \"$MCP_LINE\")\n # Process MCP result with intelligent formatting\n FORMAT_SCRIPT=\"$MCP_LIB_DIR/format_mcp_output.py\"\n if [ ! -f \"$FORMAT_SCRIPT\" ]; then\n FORMAT_SCRIPT=\"./format_mcp_output.py\" # Fallback\n fi\n if [ -f \"$FORMAT_SCRIPT\" ]; then\n echo \"$MCP_RESULT\" | python3 \"$FORMAT_SCRIPT\"\n else\n echo \"$MCP_RESULT\"\n fi\n \nelif is_bash_script \"$COMMAND\"; then\n # This is a bash command\n CMD_MAIN=$(echo \"$COMMAND\" | sed '1{/^#!\\/bin\\/bash$/d}' | sed '/^$/d' | tail -n 1)\n \n display_command \"$COMMAND\" \"bash\"\n \n # Check if it's a dangerous command\n if is_dangerous_command \"$CMD_MAIN\"; then\n if ! ask_confirmation \"⚠️ WARNING: This command is potentially dangerous!\"; then\n exit 1\n fi\n elif [ \"$CONFIRM\" = true ]; then\n if ! ask_confirmation \"Confirm execution of this command?\"; then\n exit 1\n fi\n fi\n \n echo -e \"\\033[1;32mExecuting...\\033[0m\"\n bash -c \"$CMD_MAIN\" 2>&1\n \nelse\n # Text response\n display_command \"$COMMAND\" \"text\"\n if [ \"$CONFIRM\" = true ]; then\n if ! ask_confirmation \"Does this response contain sensitive information?\"; then\n exit 1\n fi\n fi\nfi\n"}}}} |