[HN Gopher] Show HN: Magic-cli - A copilot for your command line
       ___________________________________________________________________
        
       Show HN: Magic-cli - A copilot for your command line
        
       Blog post: https://guywaldman.com/posts/introducing-magic-cli
        
       Author : guywald
       Score  : 143 points
       Date   : 2024-07-16 21:58 UTC (1 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | darby_nine wrote:
       | How's the latency?
        
         | Carrok wrote:
         | That would depend on the LLM provider you select.
        
         | deckar01 wrote:
         | It isn't streaming the ollama output so it feels slow (~3
         | words/second on a 3090 with the defaults). Using ollama
         | directly streams within a second and you can kill it early. I
         | don't understand the UX of looping responses to the same
         | question either. This does not feel like magic.
        
           | guywald wrote:
           | It's currently set not to stream
           | (https://github.com/guywaldman/magic-
           | cli/blob/4d4dca034063aa6...). The performance is something I
           | plan to improve.
        
       | Carrok wrote:
       | Default mode should probably not be "unsafe-execution" but
       | instead should be "clipboard". Make people turn on the unsafe
       | mode.
        
         | thelastparadise wrote:
         | I disagree.
         | 
         | It should be unsage execution but with an easy undo like git or
         | zfs.
        
           | Carrok wrote:
           | I eagerly await your proposal on how to undo arbitrary cli
           | commands.
        
             | IgorPartola wrote:
             | Run the code backwards!
        
               | verandaguy wrote:
               | $ man mr         MR(1)              NAME           mr,
               | relink - restore directory entries              $ mr -fr
               | /  # restore a filesystem root after deleting it
               | (recursively, forced restore)
        
               | acheong08 wrote:
               | I can't believe I just learned about this. So many lost
               | files
               | 
               | Edit: lies!
        
               | xnzakg wrote:
               | I wonder how long until <insert favorite llm> picks this
               | up and thinks it's a real command
        
             | lvncelot wrote:
             | import timetravel
        
               | usrbinbash wrote:
               | from timetravel import Delorean                  d =
               | Delorean(color="SILVER")         if d.power_gw >= 1.21:
               | d.flux_compensator.charge()             print("Great
               | Scott!")
        
             | karolist wrote:
             | What he's saying is that everything should be idempotent,
             | which may be possible for local only calls and filesystem
             | snapshots, but anything doing a network call is outside the
             | realm of this possibility. Such a system would need to spin
             | up a local, accurate backend for any network call, execute
             | the call, verify the results are not catastrophic and retry
             | with a real call, but then we also introduce time caused
             | uncertainty as the real system may drift enough from the
             | expected state during the local validation. A fun thought
             | experiment but science fiction IMHO.
        
               | mindslight wrote:
               | nit: that's not what idempotent means
        
               | karolist wrote:
               | dang, I think you're right, my mind branched off
               | somewhere it seems. I was thinking of how operations can
               | be executed multiple times (verification + actual result
               | run) with effect being applied only once.
        
             | dredmorbius wrote:
             | CoW filesystems with frequent snapshotting, which suffices
             | save for CoWFS-specific commands.
             | 
             | Spinning up a VM for testing is another Very Good Practice.
        
           | callalex wrote:
           | How do you undo, for example, an HTTP request?
        
             | neodymiumphish wrote:
             | Just rerun the command, but use UNPOST instead of POST or
             | GIVE instead of GET. Easy peasy
        
               | callalex wrote:
               | Ah, teacher always told me that HTTP is idempostent after
               | all.
        
               | sroussey wrote:
               | It's comments like this that makes me wish hn supported
               | emojis.
        
               | vinibrito wrote:
               | Ahahah oh my I never laughed so much when visiting hn.
               | Yours and the other similar comments are great. Thanks!
        
               | ku1ik wrote:
               | I like the vision where next wave of LLMs will include
               | this advice in its training set.
        
             | teaearlgraycold wrote:
             | First you need to get your modified DeLorean up to 88 miles
             | per hour.
        
           | j16sdiz wrote:
           | I disagree
           | 
           | It should be non recoverable. Everybody need to learn their
           | lesson right.
        
             | rjzzleep wrote:
             | Some ~20 years someone gave me access to their server and I
             | typed `rm -rf something _` instead of `rm -rf something_ `.
             | I have been hyper paranoid about destructive commands ever
             | since. Yesterday I wanted to setup a boot usb for bazzite
             | on a machine with two nvme drives, but I kept checking
             | multiple times that the usb drive is indeed at /dev/sda and
             | nothing else could possible be that drive even though the
             | SSD's were all on /dev/nvme0. Some hard lessons you never
             | forget.
             | 
             | ps. they had backups
        
               | xnzakg wrote:
               | Regarding the `rm` problem, `alias rm="rm -I"` makes
               | things a little safer, although no idea if this flag was
               | already a thing 20 years ago.
        
               | dredmorbius wrote:
               | In my experience, that tends to just make the approval of
               | specific file deletions reflexive.
               | 
               | The worst situation I've been in was running the classic
               | 'rm -rf' from the root filesystem, several decades ago.
               | 
               | I was running a bootable distro, had mounted all
               | filesystems but the one I was actually attempting to
               | reformat and repurpose read-only, and the upshot was that
               | I enjoyed the experience of seeing just what a system
               | which has shell internals (not sure it was even full
               | bash) and little else functions like. (I found that "echo
               | *" is a good poor-man's 'ls'.) Then, having removed the
               | filesystem I'd intended to remove in the first place (and
               | a few more ... memory-only ... filesystems), I rebooted
               | and continued.
               | 
               | What saved me was safeing all parts of the system save
               | that which I was specifically acting on. Where I've had
               | to perform similarly destructive commands elsewhere and
               | since, I've made a habit of doing similarly, ensuring I'd
               | had backups where necessary, triple-checking that what I
               | wanted to annihilate was in fact what I was going to
               | annihilate.
               | 
               | Among those practices:
               | 
               | I'll often move files or directories to a specific
               | "DELETE_ME" directory, which 1) gives a few non-
               | destructive checkpoints to destructive actions, 2) takes
               | no system time or space (file / directory moves on the
               | same filesystem don't involve copying or writing data
               | other than the filesystem metadata), then review and
               | finally delete those files.
               | 
               | I'll set all filesystems _other than those I 'm
               | specifically performing surgery on_ to "read-only". This
               | suffices for _almost_ any file-oriented actions, though
               | of course _not_ filesystem or partition operations. (
               | 'dd' is the exception to file-oriented commands, though
               | you'd have to be writing to a partition to cause
               | problems.)
               | 
               | Rather than using dynamically-generated file lists (e.g.,
               | using shell globs, 'find | xargs', $(shell expansions),
               | or similar techniques, I'll generate a one-off shell
               | script to perform complex operations. This makes explicit
               | all expansions and permits reviewing of operations before
               | committing them.
               | 
               | I'll often log complex output so that I can review the
               | operation and see if it ran as intended.
               | 
               | These have avoided numerous unpleasant surprises.
        
           | hda111 wrote:
           | How to undo a zfs destroy?
        
             | aranchelk wrote:
             | zfs create. All better.
        
             | sgarland wrote:
             | Return 0, but don't do anything yet. Fire a cron with an
             | N-minute sleep that destroys the FS on expiry. Also,
             | rewrite various ZFS tooling to lie about the consumed
             | space, and confound the user with random errors if they try
             | to use the still-allocated space.
             | 
             | /s but I sincerely hope it isn't necessary
        
           | usrbinbash wrote:
           | Alright, now I'm curious.
           | 
           | How do I "undo", say, `rm ./temp/*.txt`
        
       | h43z wrote:
       | I've never seen this extra measure "curl --proto '=https' ..."
        
         | ape4 wrote:
         | Me neither - so I looked it up at
         | https://curl.se/docs/manpage.html With the equals it means only
         | allow the named protocols.
        
           | metadat wrote:
           | What would be allowed after SSL? By default, does curl allow
           | redirects to http:// via -L?
           | 
           | If so.. that's kinda sketchy from a security perspective.
           | Especially because the flag you've shown is very unwieldy.
        
             | dijit wrote:
             | curl will not follow _any_ redirects without -L, including
             | from http to https.
             | 
             | But -L is very useful, so being able to prevent downgrades
             | has useful functionality to help restrict it.
        
               | metadat wrote:
               | This has nothing to do with what I'm attempting to
               | discuss.
        
         | guywald wrote:
         | Yep, this is auto-generated by cargo-dist
         | (https://opensource.axo.dev/cargo-dist/book/)
        
       | xp84 wrote:
       | I'm not affiliated with it, but I've been using the Warp terminal
       | program for a few months now and suspect that if you're
       | interested in this kind of thing, you might like that too.
       | 
       | In short, besides the obvious AI stuff, which works well:
       | 
       | - You can edit the command line as though it's in a GUI program
       | (including with mouse, etc) instead of it being inside the
       | terminal where you need to use different keybindings and no
       | mouse.
       | 
       | - When in a shell, instead of your window being one long stream
       | of text, each command and each output is a discrete area, so it's
       | easier to, say, select the whole output of a command.
        
         | dayjah wrote:
         | Warp also has a cool looking cataloging feature where commands
         | can be bundled up and shared with your co-workers. Seems a good
         | solution for sharing those dark arts folks tend to build up
         | over time.
         | 
         | Edit: link to feature: https://docs.warp.dev/features/blocks
        
           | scubbo wrote:
           | > Seems a good solution for sharing those dark arts folks
           | tend to build up over time
           | 
           | This is one of the things I most _dislike_ about it. Don't
           | incentivize hording those useful tools in yet-another-silo,
           | get them out into a shared code package!
        
       | bongodongobob wrote:
       | Can I ask why it's so complicated? I made something similar about
       | a year ago and it's less that 150 lines of Python. Gives you an
       | explanation, option to run it with/without sudo, pretty colors,
       | etc.
       | 
       | I guess I'm not very familiar with Rust but it just seems like a
       | lot for what it does.
        
         | guywald wrote:
         | This is a great question. I added a "Why Rust?" section to the
         | blog post to provide my rationale:
         | https://guywaldman.com/posts/introducing-magic-cli#why-rust
        
           | Lienetic wrote:
           | I assume you didn't mean to share a localhost link :)
        
             | thelastparadise wrote:
             | Would be a great way to tell someone to "fuck off" lol.
        
             | ekidd wrote:
             | Here is a corrected link:
             | https://guywaldman.com/posts/introducing-magic-cli#why-rust
        
             | guywald wrote:
             | Woops, fixed the original reply. Thanks. I guess I'm
             | excited that I got all this traction from HN ;)
        
           | thelastparadise wrote:
           | Uh buddy you linked to localhost:3000.
        
             | justusthane wrote:
             | It's what the LLM told him to do
        
               | guywald wrote:
               | I am but a mere vessel to my neural network overlords
        
             | freedomben wrote:
             | Working on my machine
        
             | mp05 wrote:
             | Thanks for the heads up, friend.
        
           | bongodongobob wrote:
           | Huh. Weird for such a simple "program" if you can even call
           | it that, but I guess I get it. Thanks.
        
       | renewiltord wrote:
       | All of these solutions seemed very heavyweight in my usage. I
       | wanted something that fit within my existing flow and using
       | copilot.vim, EDITOR=nvim, C-x C-e was the solution for me.
       | https://news.ycombinator.com/item?id=40911564
       | 
       | It's very composable and I can do incremental work with it.
        
         | beacon294 wrote:
         | You can also use esc-v to get to the editor if you switch your
         | input to vim mode with "set -o vi" in your .bashrc file.
         | 
         | Or for extra points ^[v which will serve as a handier escape,
         | as well.
        
           | renewiltord wrote:
           | Despite being vimian I've found set -o vi hard to work with.
           | Do you like it? Neovim terminal seems better for me since
           | output is selectable in the buffer.
        
             | beacon294 wrote:
             | It's a muscle you build. If you're using vim then you'll
             | like it better. You have to imagine the ex mode buffer.
        
       | rekttrader wrote:
       | We as a computing populace are getting more and more comfortable
       | with footguns.
        
         | Buttons840 wrote:
         | You imply this is a footgun. How so?
         | 
         | How is this different than looking up a random webpage with the
         | same information?
        
           | dijit wrote:
           | I mean...
           | 
           | This:
           | 
           | curl
           | google.com/?search=remove+directory+linux&feeling_lucky=1 |
           | html_strip | head -n 1 | bash
           | 
           | Is pretty dangerous, all things being equal, much more
           | dangerous than copying and pasting and of course everything
           | is more dangerous if you avoid engaging your brain entirely.
        
             | Buttons840 wrote:
             | It appears from the screenshots that this tool shows you
             | the command it will run, with some explanation of what it
             | does, and the command options used, and then confirms you
             | want to run the command. That is very different than the
             | curl command you suggested is equivalent.
        
               | imp0cat wrote:
               | suggest.mode: The mode to use for suggesting commands.
               | Supported values: "clipboard" (copying command to
               | clipboard), "unsafe-execution" (executing in the current
               | shell session) (default: "unsafe-execution")
               | 
               | So default mode seems to be shoot first, ask questions
               | later.
        
         | Closi wrote:
         | Most people are pretty comfortable copying and pasting
         | arbitrary commands they find on google and don't understand
         | into the terminal, so I'm not convinced this is any worse.
        
         | nerdjon wrote:
         | I have to agree, this to me seems like a great in theory but
         | questionable in practice.
         | 
         | We know how much damage a cli can do, they often don't have the
         | protections in place most other systems. I mean if I copy files
         | with AWS s3 there is zero confirmation that I am not overriding
         | files.
         | 
         | Personally I feel like if you really want to use an LLM to
         | generate your commands, the extra step of copying it from a
         | website is probably a good one. At least you will be forced to
         | actually look at it instead of just assume it is right and hit
         | enter.
         | 
         | The example given in the document is a simple one, but with
         | more complex CLI calls I would be scared to use this for
         | anything but the simplest of things.
         | 
         | That is ignoring the questionable decision to possibly send
         | very sensitive information to ChatGPT to generate these
         | commands.
        
       | tiberriver256 wrote:
       | I'll bet this was a lot of fun to make. Very cool project.
       | 
       | Was there any particular motive for building your own over using
       | something that's been around a bit longer like aichat?
       | 
       | https://github.com/sigoden/aichat
        
         | guywald wrote:
         | Woah, the shell features are super similar. Honestly was not
         | familiar with this project, looks great (and ambitious). I'll
         | try it out. Thanks for the share.
        
           | jimmySixDOF wrote:
           | Another approach converts into python:
           | 
           | An CLI assistant that responds by generating and auto-
           | executing a Python script. https://github.com/AbanteAI/rawdog
        
         | Lord_Zero wrote:
         | Aichat is super polished and I use it all the time. I don't see
         | why I would use anything else at this time.
        
       | icholy wrote:
       | I use https://github.com/simonw/llm-cmd
        
         | guywald wrote:
         | Awesome share! Thank you. There are definitely similarities,
         | and I love Simon's work. I guess the extra features are some
         | sophisticated UX (requesting the user to fill out
         | "placeholders" in the response, ability to revise the prompt),
         | the "ask" command and the "search" command. Will definitely
         | give this a spin.
        
       | fragmede wrote:
       | https://github.com/KillianLucas/open-interpreter/ is my preferred
       | implementation of approximately the same thing
        
       | notarealllama wrote:
       | Huh, and I'm here running llama 3 locally (and claude.ai for less
       | complex stuff), asking well formatted and specific questions and
       | still adjusting the output before implementing it.
       | 
       | Besides I need .sh scripts not just cli completion.
       | 
       | But this reminds me of warp. Gonna have to give it a spin in the
       | morning.
        
       | voodooEntity wrote:
       | Funny, i recently build something really similar ^^
       | 
       | https://github.com/voodooEntity/go-clibuddy
        
       | pmarreck wrote:
       | I have a single Bash function called "please" that basically does
       | the same thing
       | 
       | https://github.com/pmarreck/dotfiles/blob/master/bin/functio...
        
         | guywald wrote:
         | Nice! I like the `needs` utility :)
        
         | prmoustache wrote:
         | But then you need to find another alias for sudo!
        
         | gkfasdfasdf wrote:
         | What does this line do?                   [ -v EDIT ] && unset
         | EDIT && edit_function "${FUNCNAME[0]}" "$BASH_SOURCE" && return
         | 
         | Very cool script overall, thanks for sharing
        
           | pmarreck wrote:
           | Ah, forgot to include that! That's a way to edit any of my
           | functions via "edit <functionname>" and it drops you right on
           | the correct line in your $EDITOR of choice. Otherwise it
           | defaults to passing it into your editor (ostensibly a path).
           | needs() {           [ -v EDIT ] && unset EDIT &&
           | edit_function "${FUNCNAME[0]}" "$BASH_SOURCE" && return;
           | local bin="$1";           shift;           command -v "$bin"
           | > /dev/null 2>&1 || {             printf "%s is required but
           | it's not installed or in PATH; %s\n" "$bin" "$*" 1>&2;
           | return 1           }         }              contains() {
           | [ -v EDIT ] && unset EDIT && edit_function "${FUNCNAME[0]}"
           | "$BASH_SOURCE" && return;           local word;           for
           | word in $1;           do             if [[ "$word" == "$2"
           | ]]; then               return 0;             fi;
           | done;           return 1         }
           | edit_function() {           [ -v EDIT ] && unset EDIT &&
           | edit_function "${FUNCNAME[0]}" "$BASH_SOURCE" && return;
           | needs rg "please install ripgrep!";           local
           | function_name="$1";           local
           | function_name="${function_name//\?/\\?}";           local
           | file="$2";           local fl=$(rg -n -e "${function_name}
           | *\(\) *\{" -e "function +${function_name}(?: *\(\))? *\{"
           | "$file" | tail -n1 | cut -d: -f1);           $EDITOR
           | "$file":$fl         }              edit() {           [ -v
           | EDIT ] && unset EDIT && edit_function "${FUNCNAME[0]}"
           | "$BASH_SOURCE" && return;           if contains
           | "$(functions)" $1; then             EDIT=1 $1;           else
           | $EDITOR "$@";           fi         }
           | 
           | Once you have those set in your environment, and EDITOR
           | points to whatever editor you prefer, you can simply add the
           | following line to the top of any bash function you define and
           | make it editable-in-place basically:                   [ -v
           | EDIT ] && unset EDIT && edit_function "${FUNCNAME[0]}"
           | "$BASH_SOURCE" && return;
           | 
           | I use the [ -v variablename ] pattern to detect whether it's
           | set or not so that things like EDIT=1 and EDIT=true will work
           | the same way, but I've also seen ((EDIT)) used, which for
           | values of 1 gives a return code of 0 (making that expression
           | true) otherwise returns a fail, but that only works if you
           | use 1 or 0 to designate "true" and "false" for switches...
           | and it's of course confusing that you need to reverse those
           | in Bash logic which works off return codes and not actual
           | values
        
       | computatrum wrote:
       | There is also https://github.com/TNG/please-cli
        
       | teddyh wrote:
       | Beware the pitfalls of yesteryear:
       | <http://www.catb.org/~esr/jargon/html/D/DWIM.html>
        
         | compressedgas wrote:
         | https://en.wikipedia.org/wiki/Warren_Teitelman
        
         | _def wrote:
         | Funny to see this, I first came across it with
         | https://github.com/nvbn/thefuck
        
       | boomskats wrote:
       | This is nice. I've been taking Termium[0] for a spin and it's
       | been pretty great for the most part, but the Rumsfeld-complete
       | always-on autosuggest/copilot UX they're aiming for does feel
       | like a bit of a compromise.
       | 
       | On occasions when I do know what I don't know, and want to
       | specifically opt in, this looks perfect.
       | 
       | [0]: https://codeium.com/blog/termium-codeium-in-terminal-launch
        
       | Xen9 wrote:
       | The general concept is limited "command line" as means of giving
       | a single agent agency without the need to program every
       | integration separatively.
       | 
       | The AGI version is "command line" also enabling the agents to
       | communicate, modify, make each other.
        
       | pcwelder wrote:
       | I've been using https://github.com/tom-doerr/zsh_codex with
       | gpt4-o and it saves a lot of strokes as compared to github
       | copilot cli to query, since I just have to press ctrl-x in
       | addition to the prompt.
       | 
       | Magic-cli also seems to be using same workflow as github copilot,
       | so I'm not rushing to use it.
        
       | ano-ther wrote:
       | Neat. How does it compare to https://llm.datasette.io/en/stable/
       | ?
        
         | swyx wrote:
         | it's built in RUST!
        
       | kordlessagain wrote:
       | I got stuck on setting the ollama.embedding_model. No clue what
       | to do.
        
       ___________________________________________________________________
       (page generated 2024-07-17 23:13 UTC)