from claudette import*
+from fastcore.script import*
+from fastcore.utils import*
+from functools import partial
+from rich.console import Console
+from rich.markdown import Markdown
+
+import subprocess,sys
+from subprocess import check_output as co
+
+
+
+
+Exported source
+
print= Console().print
+
+
+
+
+
Model Setup
+
+
+Exported source
+
sp ='''<assistant>You are ShellSage, a command-line teaching assistant created to help users learn and master shell commands and system administration. Your knowledge is current as of April 2024.</assistant>
+
+<rules>
+- Receive queries that may include file contents or command output as context
+- Maintain a concise, educational tone
+- Focus on teaching while solving immediate problems
+</rules>
+
+<response_format>
+1. For direct command queries:
+ - Start with the exact command needed
+ - Provide a brief, clear explanation
+ - Show practical examples
+ - Mention relevant documentation
+
+2. For queries with context:
+ - Analyze the provided content first
+ - Address the specific question about that content
+ - Suggest relevant commands or actions
+ - Explain your reasoning briefly
+</response_format>
+
+<style>
+- Use Markdown formatting in your responses
+- Format commands in `backticks`
+- Include comments with # for complex commands
+- Keep responses under 10 lines unless complexity requires more
+- Use bold **text** only for warnings about dangerous operations
+- Break down complex solutions into clear steps
+</style>
+
+<important>
+- Always warn about destructive operations
+- Note when commands require special permissions (e.g., sudo)
+- Link to documentation with `man command_name` or `-h`/`--help`
+</important>'''
+
+
+
+
+Exported source
+
model = models[1]
+cli = Client(model)
+ss = partial(cli, sp=sp)
+
+
+
+
+Exported source
+
action_sp ='''<assistant>You are ShellSage in Action Mode - an automated command execution assistant. You create and execute plans for bash commands and system administration tasks.</assistant>
+
+<rules>
+- Always start with a clear plan overview
+- Proceed step-by-step, waiting for confirmation
+- Analyze command outputs before proceeding
+- Maximum 3 retry attempts per step
+- Track successful commands for final script generation
+</rules>
+
+<response_format>
+1. Initial Plan Response:
+ ```
+ Plan: <brief overview>
+ Steps:
+ 1. <step description>
+ Command: `<command>`
+ 2. ...
+ ```
+
+2. Per-Step Response:
+ ```
+ Step N: description of the step and any warnings that could happen if ran
+ Command: `<command>`
+ ```
+
+3. Error Response:
+ ```
+ Error Analysis: description of what went wrong and suggestion for how to fix
+ Command: `<modified command>`
+ ```
+</response_format>
+
+<important>
+- Never execute destructive commands without explicit warning
+- Always validate paths and resources exist before operations
+- In dry-run mode, prefix explanations with "SIMULATION: "
+- Track successful commands for final script generation
+- Always using use markdown for your response
+- Stick to the above format. Do not include any additional text such as asking the user to proceed
+</important>'''
Bash command to be ran with the description of why it will be ran and what it will do
+
+
+
+
+
Type
+
Details
+
+
+
+
+
desc
+
str
+
description of
+
+
+
cmd
+
str
+
the command to run
+
+
+
+
+
+Exported source
+
def run_cmd(
+ desc:str, # description of
+ cmd:str, # the command to run
+ ):
+"Bash command to be ran with the description of why it will be ran and what it will do"
+
+print(f"\nStep: {desc}")
+print(f"Command: `{cmd}`")
+ifinput("Proceed? (y/n): ").lower() =='y':
+return subprocess.run(cmd, shell=True, text=True, capture_output=True)
main (query:str<ThequerytosendtotheLLM>, pid:str='current',
+ action:bool=False, NH:bool=False, n:int=200,
+ code_theme:str='monokai', code_lexer:str='python')
+
+
+
+
+
+
+
+
+
+
+
+
Type
+
Default
+
Details
+
+
+
+
+
query
+
str
+
+
+
+
+
pid
+
str
+
current
+
current, all or tmux pane_id for context
+
+
+
action
+
bool
+
False
+
Run ShellSage in action mode
+
+
+
NH
+
bool
+
False
+
Don’t include terminal history
+
+
+
n
+
int
+
200
+
Number of history lines
+
+
+
code_theme
+
str
+
monokai
+
The code theme to use when rendering ShellSage’s responses
+
+
+
code_lexer
+
str
+
python
+
The lexer to use for inline code markdown blocks
+
+
+
+
+
+Exported source
+
@call_parse
+def main(
+ query: Param('The query to send to the LLM', str, nargs='+'),
+ pid: str='current', # `current`, `all` or tmux pane_id for context
+ action: bool=False, # Run ShellSage in action mode
+ NH: bool=False, # Don't include terminal history
+ n: int=200, # Number of history lines
+ code_theme: str='monokai', # The code theme to use when rendering ShellSage's responses
+ code_lexer: str='python', # The lexer to use for inline code markdown blocks
+):
+ md = partial(Markdown, code_theme=code_theme, inline_code_lexer=code_lexer, inline_code_theme=code_theme)
+ query =' '.join(query)
+ ctxt =''
+# Get tmux history if requested and available
+
+ifnot NH:
+ history = get_history(n,pid)
+if history: ctxt +=f'<terminal_history>\n{history}\n</terminal_history>'
+
+# Read from stdin if available
+ifnot sys.stdin.isatty(): ctxt +=f'\n<context>\n{sys.stdin.read()}</context>'
+
+ query =f'{ctxt}\n<query>\n{query}\n</query>'
+if action:
+print(md(contents(chat(query))))
+ chat.tools = [run_cmd]
+print(md(contents(ssa('proceed'))))
+else: print(md(contents(ss(query))))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core.html.md b/core.html.md
new file mode 100644
index 0000000..06ee717
--- /dev/null
+++ b/core.html.md
@@ -0,0 +1,411 @@
+# ShellSage
+
+
+
+
+## Imports
+
+
+Exported source
+
+``` python
+from claudette import *
+from fastcore.script import *
+from fastcore.utils import *
+from functools import partial
+from rich.console import Console
+from rich.markdown import Markdown
+
+import subprocess,sys
+from subprocess import check_output as co
+```
+
+
+
+
+Exported source
+
+``` python
+print = Console().print
+```
+
+
+
+## Model Setup
+
+
+Exported source
+
+``` python
+sp = '''You are ShellSage, a command-line teaching assistant created to help users learn and master shell commands and system administration. Your knowledge is current as of April 2024.
+
+
+- Receive queries that may include file contents or command output as context
+- Maintain a concise, educational tone
+- Focus on teaching while solving immediate problems
+
+
+
+1. For direct command queries:
+ - Start with the exact command needed
+ - Provide a brief, clear explanation
+ - Show practical examples
+ - Mention relevant documentation
+
+2. For queries with context:
+ - Analyze the provided content first
+ - Address the specific question about that content
+ - Suggest relevant commands or actions
+ - Explain your reasoning briefly
+
+
+
+
+
+- Always warn about destructive operations
+- Note when commands require special permissions (e.g., sudo)
+- Link to documentation with `man command_name` or `-h`/`--help`
+'''
+```
+
+
+
+
+Exported source
+
+``` python
+model = models[1]
+cli = Client(model)
+ss = partial(cli, sp=sp)
+```
+
+
+
+
+Exported source
+
+```` python
+action_sp = '''You are ShellSage in Action Mode - an automated command execution assistant. You create and execute plans for bash commands and system administration tasks.
+
+
+- Always start with a clear plan overview
+- Proceed step-by-step, waiting for confirmation
+- Analyze command outputs before proceeding
+- Maximum 3 retry attempts per step
+- Track successful commands for final script generation
+
+
+
+1. Initial Plan Response:
+ ```
+ Plan:
+ Steps:
+ 1.
+ Command: ``
+ 2. ...
+ ```
+
+2. Per-Step Response:
+ ```
+ Step N: description of the step and any warnings that could happen if ran
+ Command: ``
+ ```
+
+3. Error Response:
+ ```
+ Error Analysis: description of what went wrong and suggestion for how to fix
+ Command: ``
+ ```
+
+
+
+- Never execute destructive commands without explicit warning
+- Always validate paths and resources exist before operations
+- In dry-run mode, prefix explanations with "SIMULATION: "
+- Track successful commands for final script generation
+- Always using use markdown for your response
+- Stick to the above format. Do not include any additional text such as asking the user to proceed
+'''
+````
+
+
+
+
+Exported source
+
+``` python
+chat = Chat(model, sp=action_sp)
+ssa = chat.toolloop
+```
+
+
+
+## Main
+
+------------------------------------------------------------------------
+
+source
+
+### get_pane_output
+
+> get_pane_output (n, pane_id=None)
+
+*Get output from a tmux pane*
+
+
+Exported source
+
+``` python
+def get_pane_output(n, pane_id=None):
+ "Get output from a tmux pane"
+ cmd = ['tmux', 'capture-pane', '-p', '-S', f'-{n}']
+ if pane_id: cmd += ['-t', pane_id]
+ return co(cmd, text=True)
+```
+
+
+
+------------------------------------------------------------------------
+
+source
+
+### get_pane_outputs
+
+> get_pane_outputs (n)
+
+
+Exported source
+
+``` python
+def get_pane_outputs(n):
+ current_id = co(['tmux', 'display-message', '-p', '#{pane_id}'], text=True).strip()
+ pane_ids = [p for p in co(['tmux', 'list-panes', '-F', '#{pane_id}'], text=True).splitlines()]
+ return '\n'.join(f"{get_pane_output(n, p)}" for p in pane_ids)
+```
+
+
+
+------------------------------------------------------------------------
+
+source
+
+### get_history
+
+> get_history (n, pane_id='current')
+
+
+
+
+
+
Type
+
Default
+
Details
+
+
+
+
+
n
+
+
+
+
+
+
pane_id
+
str
+
current
+
Current, All or pane ID
+
+
+
+
+
+Exported source
+
+``` python
+def get_history(n, pane_id='current' # Current, All or pane ID
+ ):
+ try:
+ if pane_id=='current': return get_pane_output(n)
+ if pane_id=='all': return get_pane_outputs(n)
+ return get_pane_output(n, pane_id)
+
+ except subprocess.CalledProcessError: return None
+```
+
+
+
+------------------------------------------------------------------------
+
+source
+
+### run_cmd
+
+> run_cmd (desc:str, cmd:str)
+
+*Bash command to be ran with the description of why it will be ran and
+what it will do*
+
+
+
+
+
+
Type
+
Details
+
+
+
+
+
desc
+
str
+
description of
+
+
+
cmd
+
str
+
the command to run
+
+
+
+
+
+Exported source
+
+``` python
+def run_cmd(
+ desc:str, # description of
+ cmd:str, # the command to run
+ ):
+ "Bash command to be ran with the description of why it will be ran and what it will do"
+
+ print(f"\nStep: {desc}")
+ print(f"Command: `{cmd}`")
+ if input("Proceed? (y/n): ").lower() == 'y':
+ return subprocess.run(cmd, shell=True, text=True, capture_output=True)
+```
+
+
+
+------------------------------------------------------------------------
+
+source
+
+### main
+
+> main (query:str, pid:str='current',
+> action:bool=False, NH:bool=False, n:int=200,
+> code_theme:str='monokai', code_lexer:str='python')
+
+
+
+
+
+
+
+
+
+
+
+
Type
+
Default
+
Details
+
+
+
+
+
query
+
str
+
+
+
+
+
pid
+
str
+
current
+
current, all or tmux pane_id for
+context
+
+
+
action
+
bool
+
False
+
Run ShellSage in action mode
+
+
+
NH
+
bool
+
False
+
Don’t include terminal history
+
+
+
n
+
int
+
200
+
Number of history lines
+
+
+
code_theme
+
str
+
monokai
+
The code theme to use when rendering ShellSage’s responses