-
Notifications
You must be signed in to change notification settings - Fork 19
feat: shell hotkey integration #297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
c2ab813
ff042e4
4753188
8b3e08c
cbec3d4
5ec7f65
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import os | ||
| from pathlib import Path | ||
|
|
||
| BASH_MARKER = "# >>> cortex shell integration >>>" | ||
| ZSH_MARKER = "# >>> cortex shell integration >>>" | ||
|
|
||
|
|
||
| def _append_if_missing(rc_path: Path, block: str) -> bool: | ||
| if rc_path.exists(): | ||
| content = rc_path.read_text() | ||
| if BASH_MARKER in content: | ||
| return False | ||
| else: | ||
| rc_path.touch() | ||
|
|
||
| with rc_path.open("a", encoding="utf-8") as f: | ||
| f.write("\n" + block + "\n") | ||
|
|
||
| return True | ||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| def install_shell_integration() -> str: | ||
| shell = os.environ.get("SHELL", "") | ||
| home = Path.home() | ||
|
|
||
| if shell.endswith("bash"): | ||
| rc = home / ".bashrc" | ||
| script_path = Path(__file__).resolve().parent.parent / "scripts" / "cortex_bash.sh" | ||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| block = f"""{BASH_MARKER} | ||
| source "{script_path}" | ||
| # <<< cortex shell integration <<< | ||
| """ | ||
| installed = _append_if_missing(rc, block) | ||
| return "bash", installed | ||
|
Check warning on line 34 in cortex/shell_installer.py
|
||
|
|
||
| elif shell.endswith("zsh"): | ||
| rc = home / ".zshrc" | ||
| script_path = Path(__file__).resolve().parent.parent / "scripts" / "cortex_zsh.zsh" | ||
| block = f"""{ZSH_MARKER} | ||
| source "{script_path}" | ||
| # <<< cortex shell integration <<< | ||
| """ | ||
| installed = _append_if_missing(rc, block) | ||
| return "zsh", installed | ||
|
Check warning on line 44 in cortex/shell_installer.py
|
||
|
|
||
| else: | ||
| raise RuntimeError("Unsupported shell. Only bash and zsh are supported.") | ||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| """ | ||
| Shell integration helpers for Cortex. | ||
| This module is used by Bash/Zsh hotkey bindings to convert | ||
| natural language input into a suggested shell command. | ||
| """ | ||
|
|
||
| from typing import Optional | ||
|
|
||
|
|
||
| def suggest_command(user_input: str) -> Optional[str]: | ||
| """ | ||
| Generate a shell command suggestion from free-form user input. | ||
| Args: | ||
| user_input (str): Text currently typed in the shell. | ||
| Returns:a | ||
| Optional[str]: Suggested shell command or None if no suggestion. | ||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """ | ||
| user_input = user_input.strip() | ||
| if not user_input: | ||
| return None | ||
|
|
||
| # Import here to keep shell integration lightweight | ||
| try: | ||
| from cortex.interpreter import interpret | ||
| except Exception: | ||
| return None | ||
|
|
||
| try: | ||
| result = interpret(user_input) | ||
| except Exception: | ||
| return None | ||
|
|
||
| if not result: | ||
| return None | ||
|
|
||
| # Expected result structure: | ||
| # { | ||
| # "command": "sudo apt install docker", | ||
| # ... | ||
| # } | ||
| command = result.get("command") | ||
| if not isinstance(command, str): | ||
| return None | ||
|
|
||
| return command.strip() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # Cortex Bash shell integration | ||
| # Binds Ctrl+L to send current input to Cortex and replace it with a suggestion | ||
|
|
||
| _cortex_suggest() { | ||
|
Check warning on line 4 in scripts/cortex_bash.sh
|
||
| # READLINE_LINE contains the current command line | ||
| local input="$READLINE_LINE" | ||
|
|
||
| # Call cortex shell suggestion helper | ||
| local suggestion | ||
| suggestion="$(cortex _shell_suggest "$input" 2>/dev/null)" | ||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # If we got a suggestion, replace the current line | ||
| if [[ -n "$suggestion" ]]; then | ||
| READLINE_LINE="$suggestion" | ||
| READLINE_POINT=${#READLINE_LINE} | ||
| fi | ||
| } | ||
|
|
||
| # Bind Ctrl+L to cortex suggestion | ||
| bind -x '"\C-l": _cortex_suggest' | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Cortex Zsh shell integration | ||
| # Binds Ctrl+L to send current input to Cortex and replace it with a suggestion | ||
|
|
||
| _cortex_suggest() { | ||
| local input="$BUFFER" | ||
| local suggestion | ||
|
|
||
| suggestion="$(cortex _shell_suggest "$input" 2>/dev/null)" | ||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if [[ -n "$suggestion" ]]; then | ||
| BUFFER="$suggestion" | ||
| CURSOR=${#BUFFER} | ||
| fi | ||
| } | ||
|
|
||
| zle -N _cortex_suggest | ||
| bindkey '^L' _cortex_suggest | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| from cortex.shell_integration import suggest_command | ||
|
|
||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| def test_suggest_command_empty(): | ||
| assert suggest_command("") is None | ||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| def test_suggest_command_text(): | ||
| # We only check that it does not crash | ||
| result = suggest_command("install docker") | ||
| assert result is None or isinstance(result, str) | ||
pavanimanchala53 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Uh oh!
There was an error while loading. Please reload this page.