{"repo": "adikhan12/ai-terminal-assistant", "files": {"install_ta.sh": {"19f31f2f367a30b2f48cf6339151727c7cec3045": {"t": 1786068352.9641485, "n": 16225, "h": "be40f098e4abb7e2", "c": "#!/bin/bash\n# Terminal Assistant Installation Script for Mac\n\nset -e\n\necho \"šŸ¤– Installing Terminal Assistant...\"\n\n# Create directory\nTA_DIR=\"$HOME/.terminal_assistant\"\nmkdir -p \"$TA_DIR\"\n\n# Check for Python\nif ! command -v python3 &> /dev/null; then\n echo \"āŒ Python 3 is required but not installed.\"\n echo \"Install it with: brew install python3\"\n exit 1\nfi\n\necho \"āœ“ Python 3 found\"\n\n# Install required Python packages\necho \"šŸ“¦ Installing Python dependencies...\"\npip3 install requests --quiet\n\n# Save the main Python script\ncat > \"$TA_DIR/ta.py\" << 'EOFPYTHON'\n#!/usr/bin/env python3\n\"\"\"\nTerminal Assistant - AI-powered command line helper\nLearns from your command history and helps with suggestions\n\"\"\"\n\nimport os\nimport sqlite3\nimport json\nfrom datetime import datetime\nfrom pathlib import Path\nimport subprocess\nimport sys\n\n# DeepSeek API configuration\nDEEPSEEK_API_KEY = \"API_KEY\"\nDEEPSEEK_BASE_URL = \"https://api.deepseek.com\"\n\nclass TerminalAssistant:\n def __init__(self):\n self.db_path = Path.home() / \".terminal_assistant\" / \"commands.db\"\n self.db_path.parent.mkdir(exist_ok=True)\n self.init_database()\n \n def init_database(self):\n \"\"\"Initialize SQLite database for command history\"\"\"\n conn = sqlite3.connect(self.db_path)\n cursor = conn.cursor()\n \n cursor.execute(\"\"\"\n CREATE TABLE IF NOT EXISTS command_history (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n command TEXT NOT NULL,\n working_directory TEXT,\n exit_code INTEGER,\n timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,\n context TEXT,\n tags TEXT\n )\n \"\"\")\n \n cursor.execute(\"\"\"\n CREATE TABLE IF NOT EXISTS ssh_hosts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n hostname TEXT UNIQUE NOT NULL,\n username TEXT,\n port INTEGER DEFAULT 22,\n key_path TEXT,\n last_used DATETIME,\n usage_count INTEGER DEFAULT 0\n )\n \"\"\")\n \n cursor.execute(\"\"\"\n CREATE TABLE IF NOT EXISTS command_patterns (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n pattern_name TEXT,\n commands TEXT,\n description TEXT,\n usage_count INTEGER DEFAULT 0\n )\n \"\"\")\n \n conn.commit()\n conn.close()\n \n def log_command(self, command, working_dir=None, exit_code=0, context=None):\n \"\"\"Log a command to the database\"\"\"\n import time\n max_retries = 3\n \n for attempt in range(max_retries):\n try:\n conn = sqlite3.connect(self.db_path, timeout=10.0)\n cursor = conn.cursor()\n \n cursor.execute(\"\"\"\n INSERT INTO command_history (command, working_directory, exit_code, context)\n VALUES (?, ?, ?, ?)\n \"\"\", (command, working_dir or os.getcwd(), exit_code, context))\n \n # Extract and store SSH hosts\n if command.strip().startswith('ssh'):\n self._extract_ssh_info_safe(command, conn)\n \n conn.commit()\n conn.close()\n break\n except sqlite3.OperationalError as e:\n if attempt < max_retries - 1:\n time.sleep(0.1)\n else:\n pass # Silent fail on last attempt\n except Exception:\n break\n\n def _extract_ssh_info_safe(self, command, conn=None):\n \"\"\"Extract SSH info without opening new connection\"\"\"\n try:\n parts = command.strip().split()\n if len(parts) < 2:\n return\n \n target = parts[1] if not parts[1].startswith('-') else (parts[2] if len(parts) > 2 else None)\n if not target:\n return\n \n username = None\n hostname = target\n \n if '@' in hostname:\n username, hostname = hostname.split('@', 1)\n \n hostname = hostname.split(':')[0]\n \n should_close = False\n if conn is None:\n conn = sqlite3.connect(self.db_path, timeout=10.0)\n should_close = True\n \n cursor = conn.cursor()\n cursor.execute(\"SELECT usage_count FROM ssh_hosts WHERE hostname = ?\", (hostname,))\n existing = cursor.fetchone()\n \n if existing:\n cursor.execute(\"\"\"\n UPDATE ssh_hosts \n SET username = ?, last_used = ?, usage_count = usage_count + 1\n WHERE hostname = ?\n \"\"\", (username, datetime.now(), hostname))\n else:\n cursor.execute(\"\"\"\n INSERT INTO ssh_hosts (hostname, username, last_used, usage_count)\n VALUES (?, ?, ?, 1)\n \"\"\", (hostname, username, datetime.now()))\n \n if should_close:\n conn.commit()\n conn.close()\n except Exception:\n pass\n \n def get_recent_commands(self, limit=50):\n \"\"\"Get recent commands from history\"\"\"\n conn = sqlite3.connect(self.db_path)\n cursor = conn.cursor()\n \n cursor.execute(\"\"\"\n SELECT command, working_directory, timestamp, exit_code\n FROM command_history\n ORDER BY timestamp DESC\n LIMIT ?\n \"\"\", (limit,))\n \n results = cursor.fetchall()\n conn.close()\n return results\n \n def search_commands(self, query):\n \"\"\"Search command history\"\"\"\n conn = sqlite3.connect(self.db_path)\n cursor = conn.cursor()\n \n cursor.execute(\"\"\"\n SELECT command, working_directory, timestamp, exit_code\n FROM command_history\n WHERE command LIKE ?\n ORDER BY timestamp DESC\n LIMIT 20\n \"\"\", (f\"%{query}%\",))\n \n results = cursor.fetchall()\n conn.close()\n return results\n \n def get_ssh_hosts(self):\n \"\"\"Get all SSH hosts sorted by usage\"\"\"\n conn = sqlite3.connect(self.db_path)\n cursor = conn.cursor()\n \n cursor.execute(\"\"\"\n SELECT hostname, username, usage_count, last_used\n FROM ssh_hosts\n ORDER BY usage_count DESC, last_used DESC\n \"\"\")\n \n results = cursor.fetchall()\n conn.close()\n return results\n \n def get_context_for_ai(self):\n \"\"\"Get context to send to AI\"\"\"\n recent = self.get_recent_commands(20)\n ssh_hosts = self.get_ssh_hosts()\n \n context = {\n \"recent_commands\": [cmd[0] for cmd in recent],\n \"working_directory\": os.getcwd(),\n \"ssh_hosts\": [{\"host\": h[0], \"user\": h[1]} for h in ssh_hosts[:10]],\n \"shell\": os.environ.get(\"SHELL\", \"unknown\")\n }\n return context\n \n def query_database(self, sql_query):\n \"\"\"Execute SQL query on the database\"\"\"\n try:\n conn = sqlite3.connect(self.db_path)\n cursor = conn.cursor()\n cursor.execute(sql_query)\n results = cursor.fetchall()\n conn.close()\n return results\n except Exception as e:\n return f\"Error: {str(e)}\"\n \n def ask_ai(self, user_query):\n \"\"\"Ask AI for command suggestions using DeepSeek API\"\"\"\n import requests\n \n context = self.get_context_for_ai()\n \n system_prompt = f\"\"\"You are a helpful terminal assistant with access to the user's command history database.\n\nDATABASE SCHEMA:\n- command_history: id, command, working_directory, exit_code, timestamp, context, tags\n- ssh_hosts: id, hostname, username, port, key_path, last_used, usage_count\n- command_patterns: id, pattern_name, commands, description, usage_count\n\nCurrent context:\n- Working directory: {context['working_directory']}\n- Recent commands: {', '.join(context['recent_commands'][:5])}\n- Known SSH hosts: {', '.join([h['host'] for h in context['ssh_hosts'][:5]])}\n\nWhen the user asks about their command history (e.g., \"show my last 5 ssh connections\", \"what git commands did I run\"), respond with:\n\nSQL_QUERY: \nEXPLANATION: \n\nFor other general terminal questions, respond with:\nCOMMAND: \nEXPLANATION: \n\nExamples:\nUser: \"show me my last 5 ssh connections\"\nResponse:\nSQL_QUERY: SELECT command, timestamp FROM command_history WHERE command LIKE 'ssh %' ORDER BY timestamp DESC LIMIT 5\nEXPLANATION: This queries your Terminal Assistant database to show the last 5 SSH commands you ran with timestamps.\n\nUser: \"how do I compress a folder?\"\nResponse:\nCOMMAND: tar -czf archive.tar.gz foldername\nEXPLANATION: Creates a compressed tar archive of the folder.\n\"\"\"\n \n try:\n response = requests.post(\n f\"{DEEPSEEK_BASE_URL}/chat/completions\",\n headers={\n \"Content-Type\": \"application/json\",\n \"Authorization\": f\"Bearer {DEEPSEEK_API_KEY}\"\n },\n json={\n \"model\": \"deepseek-chat\",\n \"messages\": [\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_query}\n ],\n \"stream\": False\n }\n )\n \n if response.status_code == 200:\n result = response.json()\n ai_response = result['choices'][0]['message']['content']\n \n # Check if AI wants to query the database\n if \"SQL_QUERY:\" in ai_response:\n # Extract SQL query\n lines = ai_response.split('\\n')\n sql_query = None\n for line in lines:\n if line.startswith(\"SQL_QUERY:\"):\n sql_query = line.replace(\"SQL_QUERY:\", \"\").strip()\n break\n \n if sql_query:\n # Execute the query\n query_results = self.query_database(sql_query)\n \n # Format results\n result_text = \"\\nšŸ“Š Query Results:\\n\\n\"\n if isinstance(query_results, str):\n result_text += query_results\n elif query_results:\n for row in query_results:\n result_text += f\" {' | '.join(str(item) for item in row)}\\n\"\n else:\n result_text += \" No results found\\n\"\n \n return ai_response + \"\\n\" + result_text\n \n return ai_response\n else:\n return f\"Error: API returned {response.status_code}\"\n \n except Exception as e:\n return f\"Error calling API: {str(e)}\"\n \n def suggest_command(self, partial_command):\n \"\"\"Suggest command based on history\"\"\"\n matches = self.search_commands(partial_command)\n if matches:\n return [cmd[0] for cmd in matches[:5]]\n return []\n\n\ndef main():\n assistant = TerminalAssistant()\n \n if len(sys.argv) < 2:\n print(\"Terminal Assistant - AI-powered command helper\")\n print(\"\\nUsage:\")\n print(\" ta ask 'your question' - Ask AI for command help\")\n print(\" ta log - Log a command to history\")\n print(\" ta search - Search command history\")\n print(\" ta history - Show recent commands\")\n print(\" ta ssh - Show SSH hosts\")\n print(\" ta suggest - Get command suggestions\")\n return\n \n command = sys.argv[1]\n \n if command == \"ask\":\n if len(sys.argv) < 3:\n print(\"Usage: ta ask 'your question'\")\n return\n query = ' '.join(sys.argv[2:])\n print(f\"\\nšŸ¤– Thinking...\\n\")\n response = assistant.ask_ai(query)\n print(response)\n \n elif command == \"log\":\n if len(sys.argv) < 3:\n print(\"Usage: ta log \")\n return\n cmd = ' '.join(sys.argv[2:])\n assistant.log_command(cmd)\n print(f\"āœ“ Logged command: {cmd}\")\n \n elif command == \"search\":\n if len(sys.argv) < 3:\n print(\"Usage: ta search \")\n return\n query = ' '.join(sys.argv[2:])\n results = assistant.search_commands(query)\n print(f\"\\nšŸ“ Found {len(results)} matching commands:\\n\")\n for cmd, wd, ts, exit_code in results:\n status = \"āœ“\" if exit_code == 0 else \"āœ—\"\n print(f\"{status} {cmd}\")\n print(f\" {wd} | {ts}\\n\")\n \n elif command == \"history\":\n results = assistant.get_recent_commands(20)\n print(\"\\nšŸ“œ Recent commands:\\n\")\n for cmd, wd, ts, exit_code in results:\n status = \"āœ“\" if exit_code == 0 else \"āœ—\"\n print(f\"{status} {cmd}\")\n print(f\" {wd} | {ts}\\n\")\n \n elif command == \"ssh\":\n hosts = assistant.get_ssh_hosts()\n print(\"\\nšŸ” SSH Hosts (by usage):\\n\")\n for hostname, username, count, last_used in hosts:\n user_part = f\"{username}@\" if username else \"\"\n print(f\" {user_part}{hostname}\")\n print(f\" Used {count} times | Last: {last_used}\\n\")\n \n elif command == \"suggest\":\n if len(sys.argv) < 3:\n print(\"Usage: ta suggest \")\n return\n partial = ' '.join(sys.argv[2:])\n suggestions = assistant.suggest_command(partial)\n if suggestions:\n print(\"\\nšŸ’” Suggestions:\\n\")\n for i, cmd in enumerate(suggestions, 1):\n print(f\"{i}. {cmd}\")\n else:\n print(\"No suggestions found\")\n\n\nif __name__ == \"__main__\":\n main()\nEOFPYTHON\n\nchmod +x \"$TA_DIR/ta.py\"\necho \"āœ“ Main script installed\"\n\n# Backup existing .zshrc\nif [ -f \"$HOME/.zshrc\" ]; then\n cp \"$HOME/.zshrc\" \"$HOME/.zshrc.backup.$(date +%Y%m%d_%H%M%S)\"\n echo \"āœ“ Backed up existing .zshrc\"\nfi\n\n# Add integration to .zshrc if not already present\nif ! grep -q \"Terminal Assistant Shell Integration\" \"$HOME/.zshrc\" 2>/dev/null; then\n cat >> \"$HOME/.zshrc\" << 'EOFZSH'\n\n# Terminal Assistant Shell Integration\n# Terminal Assistant Shell Integration\nexport TA_PATH=\"$HOME/.terminal_assistant/ta.py\"\n\n# Load the hook system first\nautoload -U add-zsh-hook\n\n# NOW remove any existing hooks to prevent duplicates\nadd-zsh-hook -D preexec _ta_preexec_log\nadd-zsh-hook -D precmd _ta_precmd_log\n\n# Capture command BEFORE it runs\nfunction _ta_preexec_log() {\n _TA_LAST_CMD=\"$1\"\n}\n\n# Log after completion (only once)\nfunction _ta_precmd_log() {\n if [[ -n \"$_TA_LAST_CMD\" ]] && [[ ! \"$_TA_LAST_CMD\" =~ ^ta\\ .* ]]; then\n (python3 \"$TA_PATH\" log \"$_TA_LAST_CMD\" >/dev/null 2>&1 &)\n fi\n unset _TA_LAST_CMD\n}\n\n# Add hooks\nadd-zsh-hook preexec _ta_preexec_log\nadd-zsh-hook precmd _ta_precmd_log\n\nalias ta=\"python3 $TA_PATH\"\n\nfunction tai() {\n python3 \"$TA_PATH\" ask \"$*\"\n}\n\nfunction tah() {\n python3 \"$TA_PATH\" history\n}\n\nfunction tas() {\n python3 \"$TA_PATH\" search \"$*\"\n}\n\necho \"šŸ¤– Terminal Assistant ready! Try 'tai ' for AI help\"\nEOFZSH\n \n echo \"āœ“ Added integration to .zshrc\"\nelse\n echo \"āš ļø Integration already exists in .zshrc\"\nfi\n\necho \"\"\necho \"āœ… Installation complete!\"\necho \"\"\necho \"šŸ“ Next steps:\"\necho \"1. Restart your terminal or run: source ~/.zshrc\"\necho \"2. Try these commands:\"\necho \" tai 'how do I list files recursively?'\"\necho \" ta history\"\necho \" ta ssh\"\necho \"\"\necho \"Your commands will be automatically logged from now on!\""}}}}