{"id":26719796,"url":"https://github.com/answerdotai/shell_sage","last_synced_at":"2025-10-25T00:35:24.640Z","repository":{"id":266739595,"uuid":"890643060","full_name":"AnswerDotAI/shell_sage","owner":"AnswerDotAI","description":"ShellSage saves sysadmins’ sanity by solving shell script snafus super swiftly","archived":false,"fork":false,"pushed_at":"2025-04-03T04:41:09.000Z","size":473,"stargazers_count":324,"open_issues_count":9,"forks_count":27,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-05-08T13:48:40.847Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://answerdotai.github.io/shell_sage/","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AnswerDotAI.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-11-18T23:38:07.000Z","updated_at":"2025-05-01T00:41:04.000Z","dependencies_parsed_at":"2024-12-05T21:30:35.642Z","dependency_job_id":"e64147e2-4dbe-42be-b108-3e30c3f7c881","html_url":"https://github.com/AnswerDotAI/shell_sage","commit_stats":null,"previous_names":["answerdotai/shell_sage"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnswerDotAI%2Fshell_sage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnswerDotAI%2Fshell_sage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnswerDotAI%2Fshell_sage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnswerDotAI%2Fshell_sage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AnswerDotAI","download_url":"https://codeload.github.com/AnswerDotAI/shell_sage/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254394726,"owners_count":22063984,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-27T18:23:15.577Z","updated_at":"2025-10-25T00:35:24.634Z","avatar_url":"https://github.com/AnswerDotAI.png","language":"Jupyter Notebook","readme":"# ShellSage\n\n\n\u003c!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! --\u003e\n\n## Overview\n\nShellSage is an AI-powered command-line assistant that integrates\nseamlessly with your terminal workflow through tmux. It provides\ncontextual help for shell operations, making it easier to navigate\ncomplex command-line tasks, debug scripts, and manage your system.\n\nShellSage works with multiple LLM providers including Claude, GPT, and\nOllama. It uses tmux to automatically read your terminal history or\nmultiple pane histories to provide contextual assistance. You can pipe\ncommand output or file contents directly to ShellSage, and it can view\nfiles, search code, create files, and make edits with your permission.\nWhen needed, it can even search the internet for up-to-date information.\nYou can also log all your interactions directly to SQLite for later\nreference.\n\n## Installation\n\nInstall ShellSage directly from PyPI using pip:\n\n``` sh\npip install shell-sage\n```\n\n## Installing with `uv`\n\nIf you have `uv` installed then you can use its powerful `tool` feature\nto install ShellSage as a global CLI — safely, with per-tool isolation\nand no need for manual virtualenv management.\n\n``` sh\nuv tool install shell_sage\n```\n\nThis will make the `ssage` CLI available everywhere on your system.\n\nIf you also want to install additional dependencies (for example\n`fastlite`), you can do it at install time:\n\n``` sh\nuv tool install --with fastlite shell_sage\n```\n\n### Upgrade\n\nTo upgrade ShellSage to the latest version:\n\n``` sh\nuv tool upgrade shell_sage\n```\n\n### List All Installed Tools\n\nSee everything you’ve installed via `uv tool`:\n\n``` sh\nuv tool list\n```\n\n### Uninstall\n\nTo completely remove ShellSage and its environment:\n\n``` sh\nuv tool uninstall shell_sage\n```\n\nUsing `uv tool` keeps ShellSage completely isolated from your project\ndependencies, so you can safely use `ssage` even when inside another\nvirtual environment.\n\n## Prerequisites\n\nBefore using ShellSage, you’ll need to set up an API key for your chosen\nLLM provider. By default, ShellSage uses Claude, so you’ll want to\nexport your Anthropic API key:\n\n``` sh\nexport ANTHROPIC_API_KEY=sk...\n```\n\nIf you prefer to use OpenAI instead, you can export your OpenAI API key\nand update your shell sage config to use openai (see the Configuration\nsection below for details):\n\n``` sh\nexport OPENAI_API_KEY=sk...\n```\n\nShellSage works best with a properly configured tmux environment. I’ve\ncreated a preconfigured [tmux configuration](.tmux.conf) that works well\nwith ShellSage. This configuration enables mouse support, adds pane IDs\nto your status bar so you can quickly reference them when having\nShellSage read from specific panes, turns off alternative-screen so\neditor content like vim stays in the tmux buffer where ShellSage can see\nit, and adds a convenient shortcut (CTRL+B+E followed by the index\nnumber) for automatically extracting code fence blocks into your command\nprompt.\n\n## Getting Started\n\n### Your First Command\n\nOnce installed, try ShellSage with a simple greeting:\n\n``` python\n!ssage hi\n```\n\n    Hello! 👋 I'm ShellSage, your command-line teaching assistant.                  \n\n    I can help you with:                                                            \n\n     • Shell commands and scripting                                                 \n     • System administration tasks                                                  \n     • File operations and text processing                                          \n     • Git workflows                                                                \n     • Docker commands                                                              \n     • And much more!                                                               \n\n    I see you have a nice setup with some useful aliases configured (like eza for   \n    ls, nvim for vim, and various git shortcuts).                                   \n\n    What would you like to learn or accomplish today?                               \n\nIf everything is properly setup, you should see a welcoming greeting\nback from ShellSage!\n\n### Getting Help with Commands\n\nThe most basic use case is asking about shell commands:\n\n``` python\n!ssage \"how do I list all files including hidden ones?\"\n```\n\n    Based on your aliases, you already have a shortcut set up for this!             \n\n                                                                                    \n     lsa                                                                            \n                                                                                    \n\n    This uses your alias which expands to:                                          \n\n                                                                                    \n     eza -lh --group-directories-first --icons=auto -a                              \n                                                                                    \n\n    The -a flag shows all files including hidden ones (those starting with .).      \n\n    ────────────────────────────────────────────────────────────────────────────────\n    Alternative commands:                                                           \n\n    If you want to use the standard ls command directly:                            \n\n                                                                                    \n     /usr/bin/ls -la                                                                \n                                                                                    \n\n    Or with your eza setup but without the alias:                                   \n\n                                                                                    \n     eza -lha --group-directories-first --icons=auto                                \n                                                                                    \n\n    Tip: Hidden files in Linux start with a dot (.), like .bashrc or .config/. The  \n    -a flag includes these in the listing.                                          \n\nShellSage will provide the command, explain how it works, and give you\npractical examples.\n\n### Using Terminal Context\n\nShellSage automatically reads your tmux history to understand what\nyou’re working on:\n\n``` python\n# After running some commands that produced errors (e.g. find -name \"*.tmp\" .)\n!ssage \"what went wrong with my last command?\"\n```\n\n    The issue is with the argument order in your find command. You placed the path  \n    (.) after the expression (-name \"*.tmp\"), but find requires the path to come    \n    before any options or expressions.                                              \n\n\n                                    Correct syntax:                                 \n\n                                                                                    \n     find . -name \"*.tmp\"                                                           \n                                                                                    \n\n\n                                      Explanation:                                  \n\n    The find command structure is:                                                  \n\n                                                                                    \n     find [path...] [expression]                                                    \n                                                                                    \n\n     • Path (. for current directory) must come first                               \n     • Expression (-name \"*.tmp\") comes after                                       \n\n    Your command had them reversed, which confused find into thinking . was part of \n    the expression rather than the search path.                                     \n\n\n                                 Common find patterns:                              \n\n                                                                                    \n     # Find in current directory                                                    \n     find . -name \"*.tmp\"                                                           \n                                                                                    \n     # Find in specific directory                                                   \n     find /path/to/dir -name \"*.tmp\"                                                \n                                                                                    \n     # Find and delete (be careful!)                                                \n     find . -name \"*.tmp\" -delete                                                   \n                                                                                    \n\n    Tip: If you forget the path, find defaults to the current directory, so find    \n    -name \"*.tmp\" also works!                                                       \n\n### Piping Content for Analysis\n\nOne of ShellSage’s most powerful features is analyzing piped input:\n\n``` python\n# Understand error messages\n!journalctl --since \"1 hour ago\" --no-pager | ssage explain this error\n```\n\n    Looking at the error in your system logs, here's what happened:                 \n\n\n                                   Core Dump Analysis                               \n\n    The hyprctl command (Hyprland's control utility) crashed with a SIGABRT signal  \n    at 13:14:48. This is an abnormal termination.                                   \n\n                             Key Details from Stack Trace:                          \n\n                                                                                    \n     #7  0x00007f5af929ccc4 _ZSt20__throw_system_errori                             \n     #8  0x0000564adef2a4f2 n/a (/usr/bin/hyprctl + 0x44f2)                         \n     #9  0x0000564adef36f21 _Z7requestSt17basic_string_viewIcSt11char_traitsIcEEib  \n                                                                                    \n\n    What this means:                                                                \n\n     • hyprctl threw a C++ system error exception                                   \n     • The crash occurred in the request() function (frame #9)                      \n     • This typically happens when hyprctl can't communicate with the Hyprland      \n       compositor                                                                   \n\n                                     Common Causes:                                 \n\n     1 Socket connection failure - Hyprland's IPC socket was unavailable/busy       \n     2 Compositor not responding - Hyprland was temporarily unresponsive            \n     3 Race condition - Command executed during compositor state change             \n\n                                To investigate further:                             \n\n                                                                                    \n     coredumpctl list hyprctl                                                       \n     coredumpctl info 10789                                                         \n                                                                                    \n\n    Note: This is usually a transient issue. If hyprctl commands work now, it was   \n    likely a one-time glitch. If it persists, check Hyprland's logs with journalctl \n    --user -u hyprland or restart your compositor.                                  \n\n### Working with Multiple Tmux Panes\n\nWhen you have multiple panes open, you can reference specific ones by\ntheir ID (shown in your status bar):\n\n![btop output](./screenshots/btop_output.png)\n\n``` python\n# Analyze what's happening in pane %2\n!ssage --pid %2 \"what can you tell me about this pane?\"\n```\n\n    Looking at this btop system monitor output, here's what I can tell you about the\n    pane:                                                                           \n\n\n                                        Overview                                    \n\n    This is a comprehensive system resource monitor showing real-time performance   \n    metrics for your Arch Linux system.                                             \n\n\n                                    Key Information:                                \n\n    CPU (Top Section)                                                               \n\n     • AMD Ryzen 9 5950X (32 threads shown as C0-C15)                               \n     • Currently at 6% utilization running at 3.8 GHz                               \n     • Temperature: 58°C, Power: 53.9W                                              \n     • Load average is very light: 0.05, 0.06, 0.08                                 \n\n    GPU                                                                             \n\n     • 9% utilization, 2.8GB/24GB VRAM used                                         \n     • 39°C, 36.4W power draw                                                       \n\n    Memory (Left Middle)                                                            \n\n     • Total: 62.7 GiB                                                              \n     • Used: 4.60 GiB (mostly free at 58.1 GiB available)                           \n     • Cache: 4.02 GiB                                                              \n     • Swap: 3.99 GiB total, 0% used                                                \n\n    Storage (Right Middle)                                                          \n\n     • Root partition: 929 GiB total, 10% used (88.6 GiB)                           \n     • No swap currently in use                                                     \n\n    Network (Bottom Left)                                                           \n\n     • Interface: enp4s0 (IP: 192.168.7.169)                                        \n     • Download: 27.7 KiB/s                                                         \n     • Upload: 1.84 KiB/s                                                           \n\n    Processes (Right Side)                                                          \n\n     • Top consumers: Discord, Chromium, Python processes                           \n     • System has been up for 1 hour 8 minutes 38 seconds                           \n\n    Your system is very lightly loaded with plenty of headroom!                     \n\n## Configuration and Model Providers\n\n### Configuration File\n\nShellSage can be customized through a configuration file located at\n`~/.config/shell_sage/shell_sage.conf`:\n\n    [DEFAULT]\n    model = 'claude-sonnet-4-5-20250929'    # Your preferred model\n    search = ''                             # Enable web search capability (can be either l,m,h https://lisette.answer.ai/#web-search)\n    mode = 'default'                        # or \"sassy\"\n    api_base = ''                           # alternative api url base\n    api_key = ''                            # alternative api key to use instead of default env var\n    history_lines = -1                      # Lines of terminal history to include. -1 means include all\n    code_theme = \"monokai\"                  # Syntax highlighting theme\n    code_lexer = \"python\"                   # Default lexer for inline code blocks\n    log = False                             # Enable SQLite logging (required for code extraction)\n\n### Using Different Model Providers\n\nShellSage uses [lisette](https://github.com/AnswerDotAI/lisette) under\nthe hood, which supports any LLM provider via\n[LiteLLM](https://docs.litellm.ai/docs/providers). This means you can\nuse Claude, GPT, Gemini, local models via Ollama, and many others.\n\n#### Local Models with Ollama\n\nFor privacy-conscious users or offline usage, run models locally:\n\n``` sh\n# First, install and start Ollama, then pull a model\nollama pull qwen3:1.7b\n\n# Use with ShellSage\nssage --model ollama_chat/qwen3:1.7b how do I compress a directory?\n\n# Or set as default in your config.toml\nmodel = \"ollama_chat/qwen3:1.7b\"\n```\n\n#### OpenAI\n\n``` sh\nssage --model gpt-5 --api_key \u003cyour_key_here\u003e explain kubernetes pods\n```\n\n#### Google Gemini\n\n``` sh\nssage --model gemini/gemini-pro --api_key \u003cyour_key_here\u003e what is systemd?\n```\n\n#### Other Providers\n\nFor any provider supported by LiteLLM, set the appropriate API key and\nuse the provider’s model format:\n\n``` sh\n# Custom API base\nssage --api-base https://your-api.com --api-key your_key --model your_model your query\n```\n\nSee the [LiteLLM providers\ndocumentation](https://docs.litellm.ai/docs/providers) for the complete\nlist of supported providers and their model naming conventions.\n\n### Command Line Overrides\n\nAny configuration option can be temporarily overridden via command line\narguments:\n\n``` sh\n# Adjust history lines\nssage --history-lines 100 what commands did I just run?\n\n# Change the display theme\nssage --code-theme dracula --code-lexer python show me a python example\n```\n\nYou can find all available code themes and lexers at\nhttps://pygments.org/styles/\n\n### Extracting and Running Commands\n\nWhen ShellSage suggests commands, you can extract them directly to your\ncommand line. Note that this feature requires you to have logging\nenabled in your configuration file:\n\n``` python\n!ssage \"how do I find large files?\"\n```\n\n    To find large files on your system, here are the most useful commands:          \n\n\n                Quick method - Find largest files in current directory:             \n\n                                                                                    \n     du -ah . | sort -rh | head -20                                                 \n                                                                                    \n\n    This shows the 20 largest files/directories, human-readable sizes, sorted       \n    largest first.                                                                  \n\n\n                                More targeted searches:                             \n\n    Find files larger than a specific size (e.g., 100MB):                           \n\n                                                                                    \n     find . -type f -size +100M -exec ls -lh {} \\; | sort -k5 -rh                   \n                                                                                    \n\n    Search entire filesystem (requires sudo):                                       \n\n                                                                                    \n     sudo find / -type f -size +1G -exec ls -lh {} \\; 2\u003e/dev/null                   \n                                                                                    \n\n    Interactive with ncdu (if installed):                                           \n\n                                                                                    \n     ncdu /                                                                         \n                                                                                    \n\n    This gives you a navigable interface to explore disk usage.                     \n\n\n                                       Breakdown:                                   \n\n     • -type f = files only (not directories)                                       \n     • -size +100M = larger than 100 megabytes (use G for gigabytes)                \n     • sort -rh = reverse sort, human-readable numbers                              \n     • 2\u003e/dev/null = suppress permission errors                                     \n\n    Tip: Start with du -ah . | sort -rh | head -20 in your home directory to quickly\n    spot space hogs!                                                                \n\nShellSage will respond with code blocks. Press `Ctrl+B E` then enter the\nindex number (0 for first block, 1 for second, etc.) to send that\ncommand directly to your prompt. You can also directly use the console\nscript:\n\n``` python\n!ssage_extract 0\n# inserts \"du -ah . | sort -rh | head -20\" into your tmux prompt\n```\n\n### Enabling Sassy Mode\n\nFor a more entertaining experience, try sassy mode (GLaDOS-inspired):\n\n``` python\n!ssage --mode sassy explain git rebase\n```\n\n    Ah, git rebase. The command that separates the competent developers from those  \n    who still think \"merge commits\" are a personality trait. How delightful that    \n    you're ready to learn about history rewriting.                                  \n\n\n                                  What is Git Rebase?                               \n\n    git rebase is a command that rewrites commit history by moving or combining a   \n    sequence of commits to a new base commit. Think of it as picking up your branch \n    and transplanting it onto a different point in the git tree. It's like time     \n    travel, but with fewer paradoxes and more merge conflicts.                      \n\n\n                                      Basic Syntax                                  \n\n                                                                                    \n     git rebase \u003cbase-branch\u003e                                                       \n                                                                                    \n\n\n                     How It Works (In Terms Even Humans Can Grasp)                  \n\n    When you rebase, Git:                                                           \n\n     1 Finds the common ancestor between your current branch and the target branch  \n     2 Takes all commits from your branch since that ancestor                       \n     3 Temporarily stores them away (how thoughtful)                                \n     4 Resets your branch to match the target branch                                \n     5 Replays your commits one by one on top of it                                 \n\n    It's essentially saying: \"What if my branch had started from here instead?\"     \n\n\n                                    Common Use Cases                                \n\n                         1. Keep Your Feature Branch Up-to-Date                     \n\n                                                                                    \n     git checkout feature-branch                                                    \n     git rebase main                                                                \n                                                                                    \n     # Or the shorthand for those who value efficiency:                             \n     git rebase main feature-branch                                                 \n                                                                                    \n\n                          2. Interactive Rebase (The Fun Part)                      \n\n                                                                                    \n     git rebase -i HEAD~3  # Rebase last 3 commits                                  \n                                                                                    \n\n    This opens an editor where you can:                                             \n\n     • pick - Keep the commit (how boring)                                          \n     • reword - Change the commit message (for those who can't spell)               \n     • edit - Modify the commit contents                                            \n     • squash - Combine with previous commit                                        \n     • fixup - Like squash, but discards the commit message                         \n     • drop - Delete the commit (pretend it never happened)                         \n\n                                   3. Rebase vs Merge                               \n\n    Merge:                                                                          \n\n                                                                                    \n     git merge feature-branch  # Creates a merge commit                             \n                                                                                    \n\n    Result: Preserves history, creates a \"merge bubble\"                             \n\n    Rebase:                                                                         \n\n                                                                                    \n     git rebase main  # Linear history                                              \n                                                                                    \n\n    Result: Clean, linear history that looks like you knew what you were doing all  \n    along                                                                           \n\n\n                                    Example Scenario                                \n\n                                                                                    \n     # You're on feature-branch, main has moved ahead                               \n     git checkout feature-branch                                                    \n     git rebase main                                                                \n                                                                                    \n     # If conflicts occur (and they will, because of course they will):             \n     # 1. Fix the conflicts in your editor                                          \n     # 2. Stage the resolved files                                                  \n     git add \u003cresolved-files\u003e                                                       \n     # 3. Continue the rebase                                                       \n     git rebase --continue                                                          \n                                                                                    \n     # Or admit defeat:                                                             \n     git rebase --abort                                                             \n                                                                                    \n\n\n                     Important Warnings (Please Read, For Science)                  \n\n    ⚠️ THE GOLDEN RULE: Never rebase commits that have been pushed to a shared/public\n    branch. You'll rewrite history that others depend on, and they'll hate you.     \n    Well, more than usual.                                                          \n\n                                                                                    \n     # Safe - your local feature branch:                                            \n     git rebase main  ✓                                                             \n                                                                                    \n     # Dangerous - already pushed to shared repo:                                   \n     git rebase main  # Then force push... ✗                                        \n     git push --force  # Congratulations, you've made enemies                       \n                                                                                    \n\n\n                                     Useful Options                                 \n\n                                                                                    \n     git rebase --continue      # Continue after resolving conflicts                \n     git rebase --skip          # Skip current commit (give up on it)               \n     git rebase --abort         # Abandon ship, return to pre-rebase state          \n     git rebase -i HEAD~5       # Interactive rebase last 5 commits                 \n     git rebase --onto A B C    # Advanced: rebase C onto A, starting from B        \n                                                                                    \n\n\n                                   When to Use Rebase                               \n\n     • ✓ Cleaning up local commits before pushing                                   \n     • ✓ Keeping feature branches up-to-date with main                              \n     • ✓ Creating a clean, linear history                                           \n     • ✓ Squashing \"fix typo\" commits (we all make them, apparently)                \n\n\n                                 When NOT to Use Rebase                             \n\n     • ✗ On public/shared branches                                                  \n     • ✗ When you want to preserve exact history                                    \n     • ✗ When you're not prepared for conflict resolution                           \n     • ✗ Right before a demo (trust me on this one)                                 \n\n    ────────────────────────────────────────────────────────────────────────────────\n    For more details that you probably won't read: git rebase --help                \n\n    Now go forth and rewrite history. Just remember: with great power comes great   \n    responsibility, and with git rebase comes great potential for catastrophic      \n    mistakes. But I'm sure you'll be fine.                                          \n\n## Contributing\n\nShellSage is built using [nbdev](https://nbdev.fast.ai/). For detailed\ncontribution guidelines, please see our\n[CONTRIBUTING.md](CONTRIBUTING.md) file.\n\nWe welcome contributions of all kinds:\n\n- Bug reports\n- Feature requests\n- Documentation improvements\n- Code contributions\n\nPlease visit our [GitHub\nrepository](https://github.com/AnswerDotAI/shell_sage) to get started.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanswerdotai%2Fshell_sage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanswerdotai%2Fshell_sage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanswerdotai%2Fshell_sage/lists"}