├── LICENSE ├── README.md ├── zummoner.plugin.zsh └── zummoner.zsh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 DAY50 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Zummoner: ✨ The Zsh Spellbook ✨ 3 | 4 | **Invoke the power of the command line with a whisper!** 5 | 6 | Tired of remembering complex commands? 🧙‍♂️ Zummoner is a Zsh plugin that *summons* the right command for you, using the magic of a Large Language Model (LLM). Just describe what you want to do, and Zummoner does the rest! 7 | 8 | ![440177965-01488c16-fb68-4fdb-a7ea-76e12499641d](https://github.com/user-attachments/assets/e272d159-66c9-445a-8f82-4f545a5ddae6) 9 | 10 | 11 | ## Features - The Enchantments 🪄 12 | 13 | * **Command Conjuration:** Describe your task in plain English, and Zummoner generates the command. ✨ 14 | * **System Aware:** Knows your system (`uname -a`) and user for tailored spells. 🤖 15 | * **Modern Magic:** Prefers modern tools like `homectl`, `ip`, `systemctl`, and `journalctl`. 🚀 16 | * **Safety First:** Commands are vetted for reliability (but *always* review before running!). 🛡️ 17 | * **Customizable LLM:** Pick your favorite LLM model! 🧠 18 | * **Seamless Integration:** Works directly within your Zsh shell. 🐚 19 | 20 | ## Installation - Binding the Spirit 🔗 21 | You cann zplug, zinit, zgen it ... it's the right format orrrr manually: 22 | 23 | ```bash 24 | git clone https://github.com/day50-dev/zummoner.git $HOME/.local/zummoner 25 | echo source \$HOME/.local/zummoner/zummoner.zsh >> $HOME/.zshrc 26 | source $HOME/.zshrc 27 | 28 | ``` 29 | 30 | **Keybinding:** Zummoner uses `^Xx` (Ctrl+x, then x) by default. It'll let you know if that key is already taken! 31 | 32 | ## Usage - Uttering the Incantation 🗣️ 33 | 34 | 1. Type what you want to do (e.g., "list all files in the current directory sorted by size"). 35 | 2. Press `^Xx`. 36 | 3. Zummoner will show the command! 37 | 4. Press Enter to execute. 💥 38 | 39 | ## Caveats - A Little Magic Caution ⚠️ 40 | 41 | * **LLM Required:** Zummoner needs access to [simon w's llm](https://github.com/simonw/llm). 42 | * **Network Connection:** Requires internet access to reach the LLM. 43 | * **Review Commands:** Always check the generated command, *especially* if it uses `sudo`! 44 | * **System Differences:** Commands may need tweaking depending on your Linux distribution. 45 | 46 | ## The future! 47 | 48 | This project was a prototype [for something much more ambitious](https://news.ycombinator.com/item?id=44112949) of what is now called [ono](https://onolang.com/). 49 | -------------------------------------------------------------------------------- /zummoner.plugin.zsh: -------------------------------------------------------------------------------- 1 | source ${0:A:h}/zummoner.zsh 2 | -------------------------------------------------------------------------------- /zummoner.zsh: -------------------------------------------------------------------------------- 1 | zummoner() { 2 | local QUESTION="$BUFFER" 3 | local PROMPT=" 4 | You are an experienced Linux engineer with expertise in all Linux 5 | commands and their 6 | functionality across different Linux systems. 7 | 8 | Given a task, generate a single command or a pipeline 9 | of commands that accomplish the task efficiently. 10 | This command is to be executed in the current shell, zsh. 11 | For complex tasks or those requiring multiple 12 | steps, provide a pipeline of commands. 13 | Ensure all commands are safe and prefer modern ways. For instance, 14 | homectl instead of adduser, ip instead of ifconfig, systemctl, journalctl, etc. 15 | Make sure that the command flags used are supported by the binaries 16 | usually available in the current system or shell. 17 | If a command is not compatible with the 18 | system or shell, provide a suitable alternative. 19 | 20 | The system information is: $(uname -a) (generated using: uname -a). 21 | The user is $USER. Use sudo when necessary 22 | 23 | Create a command to accomplish the following task: $QUESTION 24 | 25 | If there is text enclosed in paranthesis, that's what ought to be changed 26 | 27 | Output only the command as a single line of plain text, with no 28 | quotes, formatting, or additional commentary. Do not use markdown or any 29 | other formatting. Do not include the command into a code block. 30 | Don't include the shell itself (bash, zsh, etc.) in the command. 31 | " 32 | local model='' 33 | 34 | if [[ -r "$HOME/$config/io.datasette.llm/default_model.txt" ]]; then 35 | model=$(cat "$HOME/$config/io.datasette.llm/default_model.txt") 36 | else 37 | model=$(llm models default) 38 | fi 39 | 40 | BUFFER="$QUESTION ... $model" 41 | zle -R 42 | local response=$(llm "$PROMPT") 43 | local COMMAND=$(echo "$response" | sed 's/```//g' | tr -d '\n') 44 | #echo "$(date %s) {$QUESTION | $response}" >> /tmp/zummoner 45 | if [[ -n "$COMMAND" ]] ; then 46 | BUFFER="$COMMAND" 47 | CURSOR=${#BUFFER} 48 | else 49 | BUFFER="$QUESTION ... no results" 50 | fi 51 | } 52 | 53 | zle -N zummoner 54 | 55 | if ! bindkey | grep -q "\^Xx"; then 56 | bindkey '^Xx' zummoner 57 | else 58 | echo "I'm not going to unbind ^Xx, you'll need to do this yourself" 59 | fi 60 | --------------------------------------------------------------------------------