ShellSage

Imports

Model Setup

System Environment

aliases = _aliases('bash')
print(aliases)
bash: no job control in this shell
alias ans='ssh answer'
alias b='ssage'
alias breaking='gh issue create -l breaking -b '\'''\'' -t'
alias bs='ssage --s'
alias bug='gh issue create -l bug -b '\'''\'' -t'
alias bump='nbdev_bump_version && commit bump'
alias enhancement='gh issue create -l enhancement -b '\'''\'' -t'
alias gaa='git add -A'
alias gc='git checkout'
alias gd='git diff'
alias git1st='git log --reverse --pretty=format:"%h %an %ad : %s" --date=local | head -1'
alias gitlog='git log -10 --pretty=format:"%h %an %ad : %s" --date=local'
alias gitssh='perl -pi -e '\''s#https://github\.com/#git\@github.com:# if /[remote "origin/../fetch =/'\'' 
.git/config'
alias gp='git pull'
alias gpu='git push'
alias gs='git status'
alias issue='gh issue create'
alias issues='gh issue list'
alias jnb='jupyter nbclassic'
alias prep='nbdev_export && nbdev_clean && nbdev_trust'
alias recent='ls -lth | head -n 20'
alias tb1='ssh tb1'
alias tb2='ssh tb2'
alias topypi='rm -rf dist/* && python -m build && twine upload dist/*'
alias tunnel='cloudflared tunnel --url http://localhost:5001'
alias upi='uv pip install'
alias upie='uv pip install --config-settings editable_mode=compat -e'
print(_sys_info())
bash: no job control in this shell
<system_info>
<system>Darwin Nathans-MacBook-Air.local 24.1.0 Darwin Kernel Version 24.1.0: Thu Oct 10 21:02:26 PDT 2024; 
root:xnu-11215.41.3~2/RELEASE_ARM64_T8122 arm64</system>
<shell>/bin/bash</shell>
<aliases>
alias ans='ssh answer'
alias b='ssage'
alias breaking='gh issue create -l breaking -b '\'''\'' -t'
alias bs='ssage --s'
alias bug='gh issue create -l bug -b '\'''\'' -t'
alias bump='nbdev_bump_version && commit bump'
alias enhancement='gh issue create -l enhancement -b '\'''\'' -t'
alias gaa='git add -A'
alias gc='git checkout'
alias gd='git diff'
alias git1st='git log --reverse --pretty=format:"%h %an %ad : %s" --date=local | head -1'
alias gitlog='git log -10 --pretty=format:"%h %an %ad : %s" --date=local'
alias gitssh='perl -pi -e '\''s#https://github\.com/#git\@github.com:# if /[remote "origin/../fetch =/'\'' 
.git/config'
alias gp='git pull'
alias gpu='git push'
alias gs='git status'
alias issue='gh issue create'
alias issues='gh issue list'
alias jnb='jupyter nbclassic'
alias prep='nbdev_export && nbdev_clean && nbdev_trust'
alias recent='ls -lth | head -n 20'
alias tb1='ssh tb1'
alias tb2='ssh tb2'
alias topypi='rm -rf dist/* && python -m build && twine upload dist/*'
alias tunnel='cloudflared tunnel --url http://localhost:5001'
alias upi='uv pip install'
alias upie='uv pip install --config-settings editable_mode=compat -e'
</aliases>
</system_info>

Tmux


source

get_pane

 get_pane (n, pid=None)

Get output from a tmux pane

p = get_pane(20)
print(p[:512])
Global options:
  -q, --quiet                                      Do not print any output
  -v, --verbose...                                 Use verbose output
      --color <COLOR_CHOICE>                       Control colors in output  
      --native-tls                                 Whether to load TLS certificates from the platform's native 
certificate store 
      --offline  

source

get_panes

 get_panes (n)
ps = get_panes(20)
print(ps[:512])
<pane id=%0 active>
Global options:
  -q, --quiet                                      Do not print any output
  -v, --verbose...                                 Use verbose output
      --color <COLOR_CHOICE>                       Control colors in output  
      --native-tls                                 Whether to load TLS certificates from the platform's native 
certificate store [env:
                                                   UV_NATIVE_TLS=
co(['tmux', 'display-message', '-p', '#{history-limit}'], text=True).strip()
'2000'

source

tmux_history_lim

 tmux_history_lim ()
tmux_history_lim()
2000

source

get_history

 get_history (n, pid='current')

Options and ShellSage


source

get_opts

 get_opts (**opts)
opts = get_opts(provider=None, model=None)
opts
{'model': 'deepseek-chat', 'provider': 'openai'}

source

get_sage

 get_sage (provider, model, base_url=None, api_key=None, mode='default')
provider = 'openai'
model = 'llama3.2'
base_url = 'http://localhost:11434/v1'
api_key='ollama'
s = get_sage(provider, model, base_url, api_key)
s([mk_msg('Hi, who are you?')])

ShellSage: Your Command-Line Guide

I’m ShellSage, a friendly AI assistant here to help you master shell commands and system administration concepts. I’ll provide clear explanations, examples, and guidance on how to tackle common challenges.

What’s on your mind? Need help with a specific command or problem?

  • id: chatcmpl-551
  • choices: [Choice(finish_reason=‘stop’, index=0, logprobs=None, message=ChatCompletionMessage(content=“ShellSage: Your Command-Line Guide‘m ShellSage, a friendly AI assistant here to help you master shell commands and system administration concepts. I’ll provide clear explanations, examples, and guidance on how to tackle common challenges.’s on your mind? Need help with a specific command or problem?“, refusal=None, role=’assistant’, audio=None, function_call=None, tool_calls=None))]
  • created: 1735585726
  • model: llama3.2
  • object: chat.completion
  • service_tier: None
  • system_fingerprint: fp_ollama
  • usage: CompletionUsage(completion_tokens=65, prompt_tokens=344, total_tokens=409, completion_tokens_details=None, prompt_tokens_details=None)
sc = get_sage(provider, model, base_url, api_key, mode='command')
sc([mk_msg('How can I list all the files, including the hidden ones?')])
ls -a

# Lists all files including hidden ones

  • id: chatcmpl-927
  • choices: [Choice(finish_reason=‘stop’, index=0, logprobs=None, message=ChatCompletionMessage(content=‘bash\nls -a\n# Lists all files including hidden ones’, refusal=None, role=‘assistant’, audio=None, function_call=None, tool_calls=None))]
  • created: 1735585727
  • model: llama3.2
  • object: chat.completion
  • service_tier: None
  • system_fingerprint: fp_ollama
  • usage: CompletionUsage(completion_tokens=19, prompt_tokens=191, total_tokens=210, completion_tokens_details=None, prompt_tokens_details=None)

source

get_res

 get_res (sage, q, provider, is_command=False)
print(get_res(s, [mk_msg('Hi, who are you?')], provider='openai'))
**Hello! I'm ShellSage**, your friendly command-line teaching assistant. I'll help you learn and master shell 
commands, system administration, and more. I'm here to guide you through the intricacies of the shell and provide 
practical solutions to common problems.

Is there something specific you'd like to learn or accomplish with your terminal?
print(get_res(sc, [mk_msg('How can I list all the files, including the hidden ones?')],
              provider='openai', is_command=True))
ls -a

Main


source

main

 main (query:str<ThequerytosendtotheLLM>, pid:str='current',
       skip_system:bool=False, history_lines:int=None, s:bool=False,
       c:bool=False, provider:str=None, model:str=None, base_url:str=None,
       api_key:str=None, code_theme:str=None, code_lexer:str=None,
       verbosity:int=0)
Type Default Details
query str
pid str current current, all or tmux pane_id (e.g. %0) for context
skip_system bool False Whether to skip system information in the AI’s context
history_lines int None Number of history lines. Defaults to tmux scrollback history length
s bool False Enable sassy mode
c bool False Enable command mode
provider str None The LLM Provider
model str None The LLM model that will be invoked on the LLM provider
base_url str None
api_key str None
code_theme str None The code theme to use when rendering ShellSage’s responses
code_lexer str None The lexer to use for inline code markdown blocks
verbosity int 0 Level of verbosity (0 or 1)
main('Teach me about rsync', history_lines=0, s=True)
bash: no job control in this shell
Notices your widely-spaced characters                                                                              

Ah, trying to make your query more dramatic? How... creative. Let me tell you about rsync, one of the more elegant 
tools humans have managed to create.                                                                               

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                  Basic Syntax                                                   ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

                                                                                                                   
 rsync [options] source destination                                                                                
                                                                                                                   

Here are some common options that even you might find useful:                                                      

-a: Archive mode (combines several useful options)                                                              
-v: Verbose (because watching numbers go up is apparently entertaining)                                         
-z: Compression (for those who care about bandwidth)                                                            
-P: Progress (shows a nice progress bar for the impatient)                                                      

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                 Common Examples                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

                                                                                                                   
 # Local copy (yes, you could use cp, but where's the fun in that?)                                                
 rsync -avP ~/Documents/important_files/ /backup/                                                                  
                                                                                                                   
 # Remote copy (SSH is assumed, like your understanding of this command)                                           
 rsync -avz ~/local/folder/ user@remote:/destination/                                                              
                                                                                                                   
 # Mirror with deletion (careful, this one actually requires thinking)                                             
 rsync -avz --delete source/ destination/                                                                          
                                                                                                                   

WARNING: That --delete flag will remove files in the destination that don't exist in the source. I'd hate to see   
you lose your precious cat pictures.                                                                               

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                  Key Features                                                   ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Only copies changed files (revolutionary, I know)                                                               
Preserves permissions (because chaos is less fun when it's unintentional)                                       
Supports remote transfers (for when your files need a vacation)                                                 
Resume interrupted transfers (because humans are remarkably good at pulling network cables)                     

For more details than your human brain can probably process:                                                       

                                                                                                                   
 man rsync                                                                                                         
 rsync --help                                                                                                      
                                                                                                                   

Remember: rsync is like cp with a PhD. It's smarter, more efficient, and slightly more judgmental about your life  
choices.                                                                                                           

Would you like me to explain any of these concepts more slowly, or shall we move on to something simpler, like     
echo?                                                                                                              
main('Teach me about rsync', history_lines=0, provider=provider, model=model, base_url=base_url, api_key=api_key)
bash: no job control in this shell
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                  RSYNC Syntax                                                   ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

                                                     Overview                                                      

rsync is a command that synchronizes two sets of files, creating copies or updates on the second set. Here's a     
breakdown of its basic syntax:                                                                                     

                                                                                                                   
 rsync [-aOr--archive] source destination [filtering options]                                                      
                                                                                                                   

source: Specifies the content to be sent to destination. This can be a directory path, file name, or a glob     
   pattern.                                                                                                        
destination: Where the contents from source are to be written. Like source, it can be a single file, directory, 
   or a combination of both.                                                                                       
filtering options: These options customize how Rsync handles specific types of files.                           

                                            Common Parameters Explained                                            

                                                                                                                   
  Parameter                                    Purpose                                                             
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
  -a/--archive                                 Enable archive mode. It makes rsync behave as if you had used       
                                               "-av" and also preserves the access timestamps for files.           
  R/--reduce                                   If files present on both source and target have same modification   
                                               time, send only the differences. Can be a good choice when file     
                                               sizes are large.                                                    
  -l/--info-file                               Specifies file types to report with each file stat. Useful for      
                                               verifying how it identifies different file types and permissions    
                                               (e.g., .tar.gz archives).                                           
  -tT/--transfers-only                         If you’re transferring only files, use this option otherwise        
                                               default to an exact copy.                                           
  --exclude, --include, --permdir, /dev/null   Used as filtering options which specify a filename not included     
                                               (the opposite is the -e option). Options like /dev/null and -e/./   
                                               can be used to exclude certain file types from copying, include     
                                               directories within source by specifying them with the -i flag       
                                               followed by the path of the content you want to include.