### Install and Run ShellGuide Source: https://github.com/walrusquant/shellguide/blob/main/README.md Instructions for cloning the repository, setting up a virtual environment, installing dependencies, and running the ShellGuide application. ```bash git clone https://github.com/WalrusQuant/shellguide.git cd shellguide python -m venv .venv source .venv/bin/activate pip install -e . shellguide ``` -------------------------------- ### Development Environment Setup and Execution Source: https://github.com/walrusquant/shellguide/blob/main/CLAUDE.md Standard commands for initializing the virtual environment, installing the package in development mode, and launching the application in different operational modes. ```bash source .venv/bin/activate pip install -e . shellguide shellguide --teach python -m shellguide ``` -------------------------------- ### Install and Launch ShellGuide Source: https://github.com/walrusquant/shellguide/blob/main/landing/index.html Commands to clone, install, and run the ShellGuide Python package. It supports both a file browser mode and an interactive teaching mode. ```bash git clone https://github.com/WalrusQuant/shellguide.git cd shellguide python -m venv .venv && source .venv/bin/activate pip install -e . # Launch file browser shellguide # Start interactive lessons shellguide --teach ``` -------------------------------- ### Launch ShellGuide Teach Mode Source: https://github.com/walrusquant/shellguide/blob/main/README.md Command to launch ShellGuide in teach mode, which provides guided interactive lessons on shell commands within a sandboxed directory. ```bash shellguide --teach ``` -------------------------------- ### GET /reference/commands Source: https://context7.com/walrusquant/shellguide/llms.txt Retrieves documentation, flag definitions, and help text for supported shell commands. ```APIDOC ## GET /reference/commands ### Description Fetches detailed reference information for a specific shell command, including flag descriptions and usage help. ### Method GET ### Endpoint /reference/commands/{command_name} ### Parameters #### Path Parameters - **command_name** (string) - Required - The name of the command (e.g., 'rm', 'ls') ### Response #### Success Response (200) - **description** (string) - Command purpose - **flags** (object) - Map of flags to their descriptions - **help_text** (string) - Formatted help string #### Response Example { "description": "Remove (delete) files and directories", "flags": {"-r": "Recursive deletion"}, "help_text": "rm — Remove files and directories..." } ``` -------------------------------- ### Access Command Reference and Help in Python Source: https://context7.com/walrusquant/shellguide/llms.txt Shows how to access a dictionary of command references, retrieve formatted help text for specific commands, and get descriptions for command strings using Python. This is useful for understanding command functionalities and their flags. ```Python from shellguide.core.command_explainer import ( COMMAND_REFERENCE, get_command_help, explain_command ) # Access command reference dictionary ls_info = COMMAND_REFERENCE["ls"] print(ls_info["description"]) # "List directory contents..." print(ls_info["flags"]["-l"]) # "Long format — shows permissions, owner, size..." print(ls_info["flags"]["-a"]) # "All files — reveals hidden files..." # Get formatted help text for a command help_text = get_command_help("rm") print(help_text) # Output: # rm — Remove (delete) files and directories — permanently, with no Trash and no undo # Flags: # -r Recursive — required for directories... # -f Force — suppresses errors and confirmation prompts... # -i Interactive — ask before each deletion... # Get command description from a command string desc = explain_command("ls -la") print(desc) # "List directory contents — see what files and folders exist..." ``` -------------------------------- ### Perform Directory Listing and Search Source: https://context7.com/walrusquant/shellguide/llms.txt Provides examples for listing directory contents with optional hidden file inclusion and performing recursive file searches. ```python from pathlib import Path from shellguide.core.file_utils import list_directory, search_files, get_disk_usage # List directory contents path = Path.home() / "Projects" files = list_directory(path, show_hidden=False) # Recursive file search results = search_files(root=Path.home() / "Projects", query="test", show_hidden=False, max_results=100) # Get disk usage usage = get_disk_usage(Path.home() / "Documents") ``` -------------------------------- ### Initialize and Launch ShellGuide Application Source: https://context7.com/walrusquant/shellguide/llms.txt Demonstrates how to instantiate the ShellGuide application class and launch it in either the default file browser mode or the interactive teach mode. ```python from shellguide.app import ShellGuideApp, main # Launch in file browser mode (default) app = ShellGuideApp() app.run() # Launch directly into teach mode app = ShellGuideApp(teach_mode=True) app.run() ``` -------------------------------- ### Python: Create Custom Challenge Validators Source: https://context7.com/walrusquant/shellguide/llms.txt Demonstrates how to create custom validators for challenge verification using ShellGuide's core components. This includes exact command matching, accepting multiple equivalent commands, handling suboptimal solutions with warnings, validating based on filesystem effects, and explaining common mistakes. ```python from shellguide.core.challenges import ( Feedback, FeedbackKind, Validator, _exact_command, _any_of, _command_with_warnings, _check_effect, _starts_with_command, _common_mistakes ) from shellguide.core.sandbox import SandboxState # Exact command match validator = _exact_command( "pwd", explanation="pwd shows your current location" ) # Accept multiple equivalent commands validator = _any_of( ["ls", "ls .", "ls ./"], explanation="ls lists directory contents" ) # Accept with warnings for suboptimal solutions validator = _command_with_warnings( accepted=["rm -r folder"], warned={"rm -rf folder": "Works, but -f is unnecessary"}, explanation="rm -r removes directories recursively" ) # Validate by checking filesystem effect validator = _check_effect( checker=lambda before, after: "newfile.txt" in after.files, explanation="File was created successfully" ) # Explain common mistakes validator = _common_mistakes( accepted=["cp -r src backup"], mistakes={ "cp src backup": ( "Without -r, cp refuses to copy directories", "cp -r src backup" ), "mv src backup": ( "mv would move the directory, not copy it", "cp -r src backup" ) }, explanation="cp -r copies directories recursively" ) ``` -------------------------------- ### Launch ShellGuide File Browser Source: https://github.com/walrusquant/shellguide/blob/main/README.md Command to launch the ShellGuide application in its default file browser mode. This mode displays a three-panel file manager and shows equivalent shell commands for user actions. ```bash shellguide ``` -------------------------------- ### Build Shell Commands with Python Source: https://context7.com/walrusquant/shellguide/llms.txt Demonstrates how to use Python functions to construct shell commands for various operations like listing directories, changing directories, creating directories, deleting files, copying files, and finding files. It also shows how to access command explanations and danger levels. ```Python from pathlib import Path from shellguide.core.command_builder import build_ls, build_cd, build_mkdir, build_rm, build_trash, build_cp, build_find # List directory cmd = build_ls(Path.home() / "Documents", show_hidden=True) print(cmd.command) # "ls -la ~/Documents" print(cmd.explanation) # "List the contents of 'Documents' in long format including hidden files..." print(cmd.danger_level) # DangerLevel.SAFE print(cmd.gui_equivalent) # "Opening a Finder window to see folder contents" # Change directory cmd = build_cd(Path.home() / "Projects") print(cmd.command) # "cd ~/Projects" # Create directory cmd = build_mkdir(Path.home() / "new_project") print(cmd.command) # "mkdir ~/new_project" print(cmd.danger_level) # DangerLevel.CAUTION # Delete commands (with danger levels) cmd = build_rm(Path.home() / "temp.txt", is_dir=False) print(cmd.command) # "rm ~/temp.txt" print(cmd.danger_level) # DangerLevel.DESTRUCTIVE cmd = build_rm(Path.home() / "temp_folder", is_dir=True) print(cmd.command) # "rm -rf ~/temp_folder" # Safe delete to trash cmd = build_trash(Path.home() / "file.txt") print(cmd.command) # "mv ~/file.txt ~/.Trash/" print(cmd.danger_level) # DangerLevel.CAUTION # Copy (with recursive flag for directories) cmd = build_cp(Path("src"), Path("backup"), is_dir=True) print(cmd.command) # "cp -r src backup" # Find files cmd = build_find(Path.home() / "Projects", "*.py") print(cmd.command) # "find ~/Projects -name '**.py*'" ``` -------------------------------- ### Sandbox Command Execution in Python Source: https://context7.com/walrusquant/shellguide/llms.txt Demonstrates how to run commands within a sandbox environment using Python. It shows how to check command success, capture errors, and handle blocked paths, commands, and operators. It also illustrates how to allow specific shell operators for chained commands. ```python result, _ = run_in_sandbox("cat /etc/passwd", cwd) print(result.success) # False print(result.error) # "Path '/etc/passwd' resolves outside the sandbox." result, _ = run_in_sandbox("curl example.com", cwd) print(result.success) # False print(result.error) # "'curl' is not available in the sandbox..." result, _ = run_in_sandbox("ls && pwd", cwd) print(result.success) # False print(result.error) # "Shell operator '&&' is not allowed..." result, new_cwd = run_in_sandbox( "mkdir test && cd test && touch main.py", cwd, allowed_operators=frozenset({"&&"}) ) print(result.success) # True (all three commands executed) result, _ = run_in_sandbox("help ls", cwd) print(result.stdout) # Detailed help for ls command ``` -------------------------------- ### Execute Safe File Operations Source: https://context7.com/walrusquant/shellguide/llms.txt Demonstrates how to perform common file system operations while retrieving the equivalent shell command and explanation for educational purposes. ```python from pathlib import Path from shellguide.core.file_ops import create_file, create_directory, rename, delete_to_trash, copy_file # Create a new empty file result = create_file(Path.home() / "new_file.txt") if result.success: print(result.shell_command.command) # Rename a file result = rename(src=Path.home() / "old_name.txt", dst=Path.home() / "new_name.txt") # Delete to trash result = delete_to_trash(Path.home() / "unwanted.txt") ``` -------------------------------- ### Execute Commands Safely within Sandbox using Python Source: https://context7.com/walrusquant/shellguide/llms.txt Demonstrates how to execute shell commands securely within a sandbox environment using Python's `run_in_sandbox` function. It shows how to check command success, capture stdout, and manage the current working directory after execution. ```Python from pathlib import Path from shellguide.core.executor import ( run_in_sandbox, ALLOWED_COMMANDS, ExecResult ) from shellguide.core.sandbox import SANDBOX_ROOT, reset_sandbox # Allowed commands in sandbox print(ALLOWED_COMMANDS) # {'ls', 'cd', 'pwd', 'mkdir', 'touch', 'rm', 'mv', 'cp', 'cat', # 'head', 'tail', 'find', 'stat', 'du', 'echo', 'wc', 'sort', # 'chmod', 'rmdir', 'help'} # Set up sandbox and execute commands reset_sandbox({"file.txt": "Hello world\n", "src": None}) cwd = SANDBOX_ROOT # Execute a command result, new_cwd = run_in_sandbox("ls -l", cwd) print(result.success) # True print(result.stdout) # "total 4\n-rw-r--r-- 1 user group 12 Jan 15 file.txt..." print(result.return_code) # 0 # cd updates the working directory result, new_cwd = run_in_sandbox("cd src", cwd) print(result.success) # True print(new_cwd) # Path("~/shellguide_sandbox/src") ``` -------------------------------- ### Challenge and Lesson System in Python Source: https://context7.com/walrusquant/shellguide/llms.txt Details the structure and usage of the Challenge and Lesson system for interactive learning. It shows how to access lessons and challenges, retrieve their properties, and validate user commands against expected outcomes, providing feedback. ```python from shellguide.core.challenges import ( Challenge, Lesson, Feedback, FeedbackKind, ALL_LESSONS, get_lesson, total_lessons ) from shellguide.core.sandbox import snapshot_sandbox, reset_sandbox print(total_lessons()) # 10 lesson = get_lesson(0) # First lesson: "Looking Around" print(lesson.id) # "looking-around" print(lesson.title) # "Looking Around" print(lesson.description) # "You just cloned a project from GitHub..." print(lesson.requires_lesson) # None (first lesson) challenge = lesson.challenges[0] print(challenge.id) # "l1-c1" print(challenge.prompt) # "See what files came with this project." print(challenge.hint) # "The command is 'ls'." print(challenge.teaching) # "When you first open a project..." print(challenge.gui_equivalent) # "Opening a Finder window..." print(challenge.mastered_command) # "ls" print(challenge.mastered_description) # "List files in current directory" print(challenge.difficulty) # 1 print(challenge.allowed_operators) # frozenset() reset_sandbox(challenge.sandbox_layout) before = snapshot_sandbox() after = snapshot_sandbox() feedback: Feedback = challenge.validate("ls", before, after) print(feedback.kind) # FeedbackKind.CORRECT print(feedback.message) # "Correct!" print(feedback.explanation) # "ls shows what's in the current directory..." feedback = challenge.validate("pwd", before, after) print(feedback.kind) # FeedbackKind.INCORRECT print(feedback.message) # "Not quite. Try again!" for i, lesson in enumerate(ALL_LESSONS): print(f"{i+1}. {lesson.title}") ``` -------------------------------- ### Implement Progressive Difficulty (Python) Source: https://github.com/walrusquant/shellguide/blob/main/ROADMAP.md Introduces progressive difficulty levels (1-3) and lesson prerequisites to the challenge system. This involves modifying the Challenge and Lesson data models, enhancing the command executor to handle chained commands, and implementing lesson gating in the UI. ```python from dataclasses import dataclass, field from typing import FrozenSet, Optional @dataclass class Challenge: difficulty: int = 1 # 1–3 allowed_operators: FrozenSet[str] = field(default_factory=frozenset) # e.g., frozenset({"&&"}) @dataclass class Lesson: requires_lesson: Optional[str] | None = None # id of prerequisite lesson ``` ```python from shellguide.core.command_builder import ShellCommand class Executor: def _check_blocked_operators(self, command_parts: list[str], allowed: frozenset[str]): # ... existing logic ... pass def _run_chained(self, commands: list[str], allowed_operators: frozenset[str]) -> bool: # Returns success status for cmd_str in commands: # Execute cmd_str, potentially using a modified run_in_sandbox # Stop on first failure success = self.run_in_sandbox(cmd_str, allowed_operators=allowed_operators) if not success: return False return True def run_in_sandbox(self, command_string: str, allowed_operators: frozenset[str]) -> bool: # Check for '&&' and if it's allowed and present if "&&" in command_string and "&&" in allowed_operators: parts = command_string.split("&&") return self._run_chained(parts, allowed_operators) else: # ... existing single command execution ... return True # Placeholder ``` ```python # In TeachScreen class (conceptual) class TeachScreen: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._completed_lessons: set[str] = set() def start_lesson(self, lesson_id): lesson = self.get_lesson(lesson_id) # Assume method to get lesson data if lesson.requires_lesson and lesson.requires_lesson not in self._completed_lessons: print(f"Please complete lesson {lesson.requires_lesson} first.") return # ... proceed to start lesson ... def on_lesson_complete(self, lesson_id): self._completed_lessons.add(lesson_id) # ... other completion logic ... def on_feedback(self, feedback_type, challenge): # ... existing logic ... if feedback_type in ("CORRECT", "ACCEPTABLE"): # Pass allowed_operators to the executor self.executor.run_in_sandbox(challenge.command, challenge.allowed_operators) # ... other logic ... ``` -------------------------------- ### Implement Dynamic Cheat Sheet (Python) Source: https://github.com/walrusquant/shellguide/blob/main/ROADMAP.md Introduces a CheatSheet data model and widget to dynamically build a cheat sheet of mastered commands as the user progresses. This involves changes to the Challenge data model and the TeachScreen. ```python from dataclasses import dataclass, field from typing import Dict, List @dataclass class CheatSheetEntry: command: str description: str lesson_id: str category: str class CheatSheet: def __init__(self): self._entries: Dict[str, CheatSheetEntry] = {} def add(self, entry: CheatSheetEntry): self._entries[entry.command] = entry def entries(self) -> List[CheatSheetEntry]: return list(self._entries.values()) def count(self) -> int: return len(self._entries) ``` ```python @dataclass class Challenge: # ... existing fields ... mastered_command: str = "" # e.g., "ls -l" mastered_description: str = "" # e.g., "List files with details" ``` ```python # In TeachScreen class (conceptual) class TeachScreen: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.cheat_sheet = CheatSheet() self.cheat_sheet_panel = CheatSheetPanel() # Assume CheatSheetPanel widget exists self.query_one(App).bind_keys({"tab": self.toggle_cheat_sheet}) def toggle_cheat_sheet(self, event): self.cheat_sheet_panel.display = not self.cheat_sheet_panel.display # Toggle visibility def on_feedback(self, feedback_type, challenge): if feedback_type in ("CORRECT", "ACCEPTABLE"): if challenge.mastered_command: entry = CheatSheetEntry( command=challenge.mastered_command, description=challenge.mastered_description, lesson_id=challenge.lesson_id, # Assuming lesson_id exists category="General" # Or derive category ) self.cheat_sheet.add(entry) self.cheat_sheet_panel.update(self.cheat_sheet.entries_by_category()) # Assume update method ``` -------------------------------- ### Cheat Sheet System in Python Source: https://context7.com/walrusquant/shellguide/llms.txt Illustrates the creation and management of a cheat sheet to track mastered commands. It shows how to add entries with command details, descriptions, lesson IDs, and categories, and how to access and group these entries. ```python from shellguide.core.cheat_sheet import CheatSheet, CheatSheetEntry sheet = CheatSheet() sheet.add(CheatSheetEntry( command="ls", description="List files in current directory", lesson_id="looking-around", category="Looking Around" )) sheet.add(CheatSheetEntry( command="ls -l", description="List files with details", lesson_id="looking-around", category="Looking Around" )) sheet.add(CheatSheetEntry( command="cd