### Developer Setup for PyCSH Source: https://github.com/spaceinventor/pycsh/blob/master/README.md Commands for cloning the PyCSH repository with submodules, configuring the build environment, and optionally installing the library in editable mode. ```bash git clone --recurse-submodules https://github.com/spaceinventor/PyCSH.git cd PyCSH ./configure # Build & Install (system-wide, no API docs) ./install # Install repo as package (affects system-wide imports, includes API docs) pip3 -e install. # Build (No install) ./build ``` -------------------------------- ### Install PyCSH from GitHub Source: https://github.com/spaceinventor/pycsh/blob/master/README.md Installs the PyCSH library directly from its GitHub repository using pip. This is useful for getting the latest version or for inclusion in project requirements. ```bash pip install git+https://github.com/spaceinventor/PyCSH.git ``` -------------------------------- ### Concrete Example: Extending 'reboot' Slash Command Source: https://github.com/spaceinventor/pycsh/wiki/Using-PyCSH-to-create-an-APM-extension-for-CSH This concrete example extends the 'reboot' slash command. It defines a new 'reboot' function that checks arguments to decide whether to reboot the current node. If specific conditions are met (e.g., attempting to reboot node '0' with '-n' flag), it prints a message and refuses; otherwise, it calls the original 'reboot' command. ```python _original_reboot = pycsh.SlashCommand("reboot") def reboot(*args: tuple[str]) -> None: reboot_self = False if '-n' in args and args[args.index('-n' + 1)] == '0': reboot_self = True elif args[0] == '0': reboot_self = True if reboot_self: # Refuse to reboot node 0 print("Refusing to reboot self") else: # Execute original (overridden) command, with whatever arguments we were given _original_reboot(*args) _reboot = pycsh.PythonSlashCommand("reboot", reboot, _original_reboot.args) ``` -------------------------------- ### Install Dependencies for PyCSH Source: https://github.com/spaceinventor/pycsh/blob/master/README.md Installs necessary system libraries and build tools required for compiling and running PyCSH. This includes development headers for various libraries like libcurl, libsocketcan, and Python, as well as build systems like meson and ninja. ```bash sudo apt install libcurl4-openssl-dev git build-essential libsocketcan-dev can-utils libzmq3-dev pkg-config pipx libelf-dev libbsd-dev python3-dev pipx install meson ninja ``` -------------------------------- ### Basic PyCSH Usage Example Source: https://github.com/spaceinventor/pycsh/blob/master/README.md Demonstrates the basic initialization steps for using the PyCSH library in a Python script. It includes initializing the core PyCSH library and the CSP (communication services protocol) interface. ```python import pycsh def main(): pycsh.init() pycsh.csp_init() # if __name__ == '__main__': main() ``` -------------------------------- ### Extend Existing Slash Command with PyCSH Source: https://github.com/spaceinventor/pycsh/wiki/Using-PyCSH-to-create-an-APM-extension-for-CSH This example shows how to extend an existing slash command using PyCSH. It involves retrieving the original command, defining a new Python function to wrap its execution, and then registering this new function as a PythonSlashCommand with the same name. This allows for pre- or post-execution logic, or conditional execution of the original command. ```python _original_command = pycsh.SlashCommand() def command(*args: tuple[str]) -> None: """ This is Python command that extends an existing command """ # ... Extend original command here ... # Extending command may of course opt out of calling the original. if : return # Call the original slash command, with whatever argument we received. _original_reboot(*args) # ... Perhaps do something after the original command has executed ... _command = pycsh.PythonSlashCommand(, command, _original_command.args) ``` -------------------------------- ### Get and Set Integer Parameters with pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Demonstrates direct access to integer parameters using CSH-style get and set functions in PyCSH. Parameters can be identified by their integer ID or string name. The example shows retrieving, modifying, and restoring an integer parameter's value. ```python import pycsh pycsh.init() pycsh.node(0) # Get parameter value by ID original_value = pycsh.get(202) print(f"Parameter 202 value: {original_value}") # Set parameter value by ID pycsh.set(202, original_value + 3) # Verify the change new_value = pycsh.get(202) print(f"Updated value: {new_value}") # Restore original value pycsh.set(202, original_value) ``` -------------------------------- ### PyCSH Installation in requirements.txt Source: https://github.com/spaceinventor/pycsh/blob/master/README.md Specifies how to include PyCSH as a dependency in a Python project's `requirements.txt` file using a Git reference. This ensures reproducible builds. ```bash -e git+https://github.com/spaceinventor/PyCSH.git ``` -------------------------------- ### Initialization and Node Configuration Source: https://context7.com/spaceinventor/pycsh/llms.txt Initializes the PyCSH module, starts the CSP thread, and sets the default node for parameter operations. This must be called before any other PyCSH functions. ```APIDOC ## Initialize PyCSH and Set Node ### Description Initializes the PyCSH module, starts the CSP thread, and sets the default node for parameter operations. This must be called before any other PyCSH functions. ### Method N/A (Initialization Function) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import pycsh from subprocess import DEVNULL # Initialize the module - starts CSP thread pycsh.init(stdout=DEVNULL) # Set default node to local (0) pycsh.node(0) # Get current default node current_node = pycsh.node() print(f"Default node: {current_node}") ``` ### Response #### Success Response (N/A) This function primarily performs setup operations and does not return a specific data structure for success. #### Response Example ``` Default node: 0 ``` ``` -------------------------------- ### Create Python Slash Command with PyCSH Source: https://github.com/spaceinventor/pycsh/wiki/Using-PyCSH-to-create-an-APM-extension-for-CSH This snippet demonstrates how to define a new slash command in Python using PyCSH. It imports the pycsh library, defines a function to be executed by the command, and then registers it as a PythonSlashCommand. The command takes a single string argument. ```python """ Python APM test """ from __future__ import annotations # Import pycsh, which will be linked to CSH when imported as an APM import pycsh def inform(name: str) -> None: """ This is the function that our slash command will execute, notice that it accepts the argument """ print(f"Hej {name}, nu kan du lave APMer i Python :)") # Calls to pycsh.PythonSlashCommand() create new slash commands. # Here we create a command called "inform" that runs the function inform(). # Optionally an 'argument' string may be specified, which is what "help" in CSH will show. # When commands are instantiated on global scope, # they will not be recreated if their module is imported/executed multiple times. _inform = pycsh.PythonSlashCommand("inform", inform, "") def main() -> None: """ The "py run" command in CSH will currently execute main() by default, this may be changed by the "-f" argument """ # Our slash command may also be invoked here through Python _inform("mig selv") ``` -------------------------------- ### Get and Set Integer Parameters Source: https://context7.com/spaceinventor/pycsh/llms.txt Provides direct access to integer parameters using their ID or name. Allows retrieving and modifying parameter values. ```APIDOC ## Get and Set Integer Parameters ### Description Provides direct access to integer parameters using their ID or name. Allows retrieving and modifying parameter values. ### Method N/A (Function Calls) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import pycsh pycsh.init() pycsh.node(0) # Get parameter value by ID original_value = pycsh.get(202) print(f"Parameter 202 value: {original_value}") # Set parameter value by ID pycsh.set(202, original_value + 3) # Verify the change new_value = pycsh.get(202) print(f"Updated value: {new_value}") # Restore original value pycsh.set(202, original_value) ``` ### Response #### Success Response (200) - **`original_value`** (int) - The current value of the parameter. - **`new_value`** (int) - The updated value of the parameter. #### Response Example ``` Parameter 202 value: 10 Updated value: 13 ``` ``` -------------------------------- ### Initialize PyCSH and Set Node Source: https://context7.com/spaceinventor/pycsh/llms.txt Initializes the PyCSH module, starting the CSP thread and setting the default node for parameter operations. It requires the 'pycsh' library and optionally redirects standard output. The default node is set to '0' (local). ```python import pycsh from subprocess import DEVNULL # Initialize the module - starts CSP thread pycsh.init(stdout=DEVNULL) # Set default node to local (0) pycsh.node(0) # Get current default node current_node = pycsh.node() print(f"Default node: {current_node}") ``` -------------------------------- ### Ping and Ident Commands in pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Performs network diagnostics using CSP protocol. Includes pinging a node to measure response time and retrieving a node's identification string. Also shows how to get the parameter version and the type of a parameter by its ID. Requires pycsh initialization. ```python import pycsh pycsh.init() pycsh.node(0) # Ping a node and get response time in milliseconds response_time = pycsh.ping(0) print(f"Ping response: {response_time} ms") # Get node identification string ident_info = pycsh.ident(0) print(f"Node identification: {ident_info}") # Get current parameter version param_version = pycsh.paramver() print(f"Parameter version: {param_version}") # Get parameter type by ID param_type = pycsh.get_type(200) print(f"Type of parameter 200: {param_type}") ``` -------------------------------- ### String Parameter Operations with pycsh.Parameter Source: https://context7.com/spaceinventor/pycsh/llms.txt Demonstrates handling string parameters using the PyCSH 'Parameter' class. String parameters, backed by character arrays, can be manipulated as Python strings. The example shows setting values, accessing characters by index, and checking lengths. ```python import pycsh pycsh.init() pycsh.node(0) # Create string parameter instance col_cnfstr = pycsh.Parameter(200) # Store original value original_value = col_cnfstr.value print(f"Original: {original_value}") # Set string value col_cnfstr.value = "Hello World!" print(f"New value: {col_cnfstr.value}") # Index access (read-only) first_char = col_cnfstr[0] print(f"First character: {first_char}") # Length comparison print(f"Parameter length: {len(col_cnfstr)}") print(f"String length: {len(col_cnfstr.value)}") # Restore original col_cnfstr.value = original_value ``` -------------------------------- ### Parameter Lists and Batch Operations Source: https://context7.com/spaceinventor/pycsh/llms.txt Introduces `ParameterList` for managing collections of parameters. Supports batch operations like listing all parameters, downloading from a node, and batch pulling/pushing values. ```APIDOC ## Parameter Lists and Batch Operations ### Description Introduces `ParameterList` for managing collections of parameters. Supports batch operations like listing all parameters, downloading from a node, and batch pulling/pushing values. ### Method N/A (Function Calls and Class Instantiation) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import pycsh pycsh.init() pycsh.node(0) # Get all available parameters parameter_list = pycsh.list() # Print parameter names print("Available parameters:") for param in parameter_list: print(f" {param.name}") # Download parameters from a remote node downloaded_list = pycsh.list_download(0) print(f"Downloaded {len(downloaded_list)} parameters") # Filter parameters by type int_params = pycsh.ParameterList([p for p in parameter_list if p.type is int]) print(f"Integer parameters: {len(int_params)}") # Batch pull values from node int_params.pull(0) # Batch push values to node (useful when autosend=0) int_params.push(0) ``` ### Response #### Success Response (200) - **`parameter_list`** (list of Parameter objects) - A list of all available parameters. - **`downloaded_list`** (list of Parameter objects) - Parameters downloaded from the specified node. - **`int_params`** (ParameterList object) - A filtered list containing only integer parameters. #### Response Example ``` Available parameters: col_verbose col_cnfstr array_param Downloaded 150 parameters Integer parameters: 75 ``` ``` -------------------------------- ### Create New Parameters with pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Demonstrates creating new parameters dynamically with specified types, access permissions, and documentation. New parameters are added to the parameter list and can be accessed by their ID or name after creation. This requires pycsh initialization and setting the current node. ```python import pycsh pycsh.init() pycsh.node(0) # Create a new integer parameter normal_param = pycsh.Parameter.new( 300, 'normal_param', pycsh.PARAM_TYPE_UINT8, pycsh.PM_CONF, 1, None, '', 'A new parameter for testing' ) # Add to parameter list normal_param.list_add() # Now it can be accessed by ID or name retrieved = pycsh.Parameter(300) print(f"Retrieved: {retrieved.name}") # Set and get value normal_param.value = 42 print(f"Value: {normal_param.value}") ``` -------------------------------- ### Parameter Lists and Batch Operations with pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Introduces 'ParameterList' for efficient batch operations on multiple parameters. It supports listing all available parameters, downloading parameters from remote nodes, filtering by type, and performing synchronized pull/push operations across a CSP network. ```python import pycsh pycsh.init() pycsh.node(0) # Get all available parameters parameter_list = pycsh.list() # Print parameter names print("Available parameters:") for param in parameter_list: print(f" {param.name}") # Download parameters from a remote node downloaded_list = pycsh.list_download(0) print(f"Downloaded {len(downloaded_list)} parameters") # Filter parameters by type int_params = pycsh.ParameterList([p for p in parameter_list if p.type is int]) print(f"Integer parameters: {len(int_params)}") # Batch pull values from node int_params.pull(0) # Batch push values to node (useful when autosend=0) int_params.push(0) ``` -------------------------------- ### Array Parameter Indexing and Slicing in PyCSH Source: https://context7.com/spaceinventor/pycsh/llms.txt Demonstrates advanced manipulation of array parameters using PyCSH. It covers creating new array parameters, setting all elements at once, accessing individual elements by index, and performing Python-style slicing operations. This is useful for handling buffer-like parameters. ```python import pycsh pycsh.init() pycsh.node(0) # Create an array parameter (8 elements) array_param = pycsh.Parameter.new( 301, 'array_param', pycsh.PARAM_TYPE_UINT8, pycsh.PM_CONF, 8, None, '', 'Test array parameter' ) array_param.list_add() # Set all elements at once array_param.value = (0, 1, 2, 3, 4, 5, 6, 7) # Access individual elements print(f"Element 0: {array_param[0]}") print(f"Element 5: {array_param[5]}") # Slice operations print(f"Elements 5 to end: {array_param[5:]}") print(f"Elements 5 to -1: {array_param[5:-1]}") print(f"Reversed: {array_param[::-1]}") ``` -------------------------------- ### Parameter Callbacks in pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Enables event-driven monitoring by registering callback functions that are executed when a parameter's value changes. The callback function must accept a pycsh.Parameter object and an index as arguments. Initialization and node selection are prerequisites. ```python import pycsh pycsh.init() pycsh.node(0) # Create a parameter param = pycsh.Parameter.new( 300, 'callback_param', pycsh.PARAM_TYPE_UINT8, pycsh.PM_CONF, 1, None, '', 'Parameter with callback' ) param.list_add() # Define callback with required signature def on_change(param: pycsh.Parameter, index: int) -> None: print(f"Parameter {param.name} changed at index {index}") print(f"New value: {param.value}") # Assign callback param.callback = on_change # Trigger callback by changing value param.value = 100 # Callback will be invoked ``` -------------------------------- ### Array Parameter Indexing and Slicing Source: https://context7.com/spaceinventor/pycsh/llms.txt Enables interaction with array-type parameters. Supports Python-style indexing, slicing, and broadcasting for element-wise modification and retrieval. ```APIDOC ## Array Parameter Indexing and Slicing ### Description Enables interaction with array-type parameters. Supports Python-style indexing, slicing, and broadcasting for element-wise modification and retrieval. ### Method N/A (Class Method and Instance Access) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import pycsh pycsh.init() pycsh.node(0) # Create an array parameter (8 elements) array_param = pycsh.Parameter.new( 301, 'array_param', pycsh.PARAM_TYPE_UINT8, pycsh.PM_CONF, 8, None, '', 'Test array parameter' ) array_param.list_add() # Set all elements at once array_param.value = (0, 1, 2, 3, 4, 5, 6, 7) # Access individual elements print(f"Element 0: {array_param[0]}") print(f"Element 5: {array_param[5]}") # Slice operations print(f"Elements 5 to end: {array_param[5:]}") print(f"Elements 5 to -1: {array_param[5:-1]}") print(f"Reversed: {array_param[::-1]}") ``` ### Response #### Success Response (200) - **`array_param.value`** (tuple) - The current values of the array parameter. - **`array_param[index]`** (int/float/etc.) - The value of the element at the specified index. - **`array_param[slice]`** (tuple) - A tuple containing the values within the specified slice. #### Response Example ``` Element 0: 0 Element 5: 5 Elements 5 to end: (5, 6, 7) Elements 5 to -1: (5, 6) Reversed: (7, 6, 5, 4, 3, 2, 1, 0) ``` ``` -------------------------------- ### Add Parameters to List with list_add in pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Demonstrates the process of adding parameters to the CSH parameter list using the `list_add` method. This is a crucial step after creating a new parameter using `Parameter.new` to make it discoverable and accessible within the CSH environment. It's also implied that this method can handle updates to existing parameters. ```python import pycsh pycsh.init() pycsh.node(0) ``` -------------------------------- ### Broadcast Value to All Elements in pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Broadcasts a specified value to all elements within an array parameter. This is useful for initializing or updating multiple parameter elements simultaneously. It assumes 'array_param' is a pre-existing array-like parameter object. ```python array_param[:] = 10 print(f"All elements: {array_param.value}") ``` -------------------------------- ### String Parameter Operations Source: https://context7.com/spaceinventor/pycsh/llms.txt Handles string parameters, allowing them to be manipulated using Python strings. Supports basic string operations like assignment, indexing, and slicing. ```APIDOC ## String Parameter Operations ### Description Handles string parameters, allowing them to be manipulated using Python strings. Supports basic string operations like assignment, indexing, and slicing. ### Method N/A (Class Instantiation and Attribute Access) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import pycsh pycsh.init() pycsh.node(0) # Create string parameter instance col_cnfstr = pycsh.Parameter(200) # Store original value original_value = col_cnfstr.value print(f"Original: {original_value}") # Set string value col_cnfstr.value = "Hello World!" print(f"New value: {col_cnfstr.value}") # Index access (read-only) first_char = col_cnfstr[0] print(f"First character: {first_char}") # Length comparison print(f"Parameter length: {len(col_cnfstr)}") print(f"String length: {len(col_cnfstr.value)}") # Restore original col_cnfstr.value = original_value ``` ### Response #### Success Response (200) - **`original_value`** (str) - The original string value of the parameter. - **`new_value`** (str) - The updated string value of the parameter. - **`first_char`** (str) - The character at the first index. - **`len(col_cnfstr)`** (int) - The length of the parameter's string value. - **`len(col_cnfstr.value)`** (int) - The length of the Python string. #### Response Example ``` Original: SomeDefaultString New value: Hello World! First character: H Parameter length: 12 String length: 12 ``` ``` -------------------------------- ### Parameter Class for Object-Oriented Access Source: https://context7.com/spaceinventor/pycsh/llms.txt Offers an object-oriented approach to parameter management. The `Parameter` class allows accessing parameter metadata and values through attributes. ```APIDOC ## Parameter Class for Object-Oriented Access ### Description Offers an object-oriented approach to parameter management. The `Parameter` class allows accessing parameter metadata and values through attributes. ### Method N/A (Class Instantiation and Attribute Access) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import pycsh pycsh.init() pycsh.node(0) # Create Parameter instance by ID col_verbose = pycsh.Parameter(202) # Access parameter metadata print(f"Name: {col_verbose.name}") print(f"Node: {col_verbose.node}") print(f"Type: {col_verbose.type}") # Get and set value through the instance original = col_verbose.value print(f"Original value: {original}") # Modify the value col_verbose.value = original + 5 print(f"New value: {col_verbose.value}") # Restore original col_verbose.value = original ``` ### Response #### Success Response (200) - **`name`** (str) - The name of the parameter. - **`node`** (int) - The node ID where the parameter resides. - **`type`** (int) - The data type of the parameter. - **`value`** (various) - The current value of the parameter. #### Response Example ``` Name: col_verbose Node: 0 Type: 3 Original value: 10 New value: 15 ``` ``` -------------------------------- ### VMEM Operations in pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Manages virtual memory (VMEM) parameters, which are typically used for persistent storage. The provided code demonstrates how to list all available VMEM parameters. Placeholder comments indicate where additional operations like restoring, backing up, or unlocking VMEM might be implemented. ```python import pycsh pycsh.init() pycsh.node(0) # List all VMEM parameters vmem_list = pycsh.vmem_list() print("VMEM parameters:") print(vmem_list) # Additional VMEM operations (when available): # pycsh.vmem_restore() # Restore from backup # pycsh.vmem_backup() # Create backup # pycsh.vmem_unlock() # Unlock VMEM ``` -------------------------------- ### Add and Update Parameter with PyCSH Source: https://context7.com/spaceinventor/pycsh/llms.txt Demonstrates adding a new parameter and subsequently updating its type using `pycsh.list_add`. The function handles both initial creation and modification of parameters based on their ID. It showcases setting various attributes and printing the results. ```python import pycsh # Add a parameter using the list_add function new_param = pycsh.list_add( node=0, array_size=1, param_id=350, name='dynamic_param', param_type=pycsh.PARAM_TYPE_UINT16, mask=pycsh.PM_CONF, docstr='Dynamically added parameter', unit='units' ) print(f"Added parameter: {new_param.name}") print(f"Type: {new_param.c_type}") # Adding again with different type updates existing parameter updated_param = pycsh.list_add( node=0, array_size=1, param_id=350, name='dynamic_param', param_type=pycsh.PARAM_TYPE_UINT32, mask=pycsh.PM_CONF, docstr='Updated parameter', unit='units' ) print(f"Updated type: {updated_param.c_type}") ``` -------------------------------- ### Remote Parameter Access with pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Facilitates access and modification of parameters residing on remote nodes within the CSP network. It involves initializing pycsh potentially with a custom configuration, downloading the remote parameter list, and then interacting with remote parameters as if they were local. A `sleep` is often needed to ensure operations complete. ```python import pycsh from time import sleep from subprocess import DEVNULL # Initialize with custom configuration pycsh.init(yamlname="local.yaml", stdout=DEVNULL) # Download remote parameter list REMOTE_NODE = 18 pycsh.list_download(REMOTE_NODE) # Create Parameter object for remote parameter remote_param = pycsh.Parameter('some_parameter', node=REMOTE_NODE) # Read remote value print(f"Remote value: {remote_param.value}") # Modify remote parameter if remote_param.type is str: remote_param.value = "changed remotely" else: remote_param.value += 1 print(f"Updated remote value: {remote_param.value}") ``` -------------------------------- ### Create Custom Slash Commands with Python in pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Allows extension of the CSH environment by defining custom slash commands implemented in Python. A Python function is registered with pycsh, making it callable directly from the CSH prompt or programmatically. This requires a function definition and registration using `pycsh.PythonSlashCommand`. ```python import pycsh # Define command function def inform(name: str) -> None: print(f"Hello {name}, you can now create APMs in Python!") # Register as slash command # Arguments: command_name, function, argument_help_string _inform = pycsh.PythonSlashCommand("inform", inform, "") # The command can now be invoked from CSH: # > inform "World" # Or called directly in Python: _inform("directly from Python") ``` -------------------------------- ### Object-Oriented Parameter Access with pycsh.Parameter Source: https://context7.com/spaceinventor/pycsh/llms.txt Utilizes the 'Parameter' class in PyCSH for an object-oriented approach to parameter management. It allows accessing parameter metadata (name, node, type) and values through direct attribute access. Changes to the '.value' attribute are automatically applied. ```python import pycsh pycsh.init() pycsh.node(0) # Create Parameter instance by ID col_verbose = pycsh.Parameter(202) # Access parameter metadata print(f"Name: {col_verbose.name}") print(f"Node: {col_verbose.node}") print(f"Type: {col_verbose.type}") # Get and set value through the instance original = col_verbose.value print(f"Original value: {original}") # Modify the value col_verbose.value = original + 5 print(f"New value: {col_verbose.value}") # Restore original col_verbose.value = original ``` -------------------------------- ### Override Existing Slash Commands in pycsh Source: https://context7.com/spaceinventor/pycsh/llms.txt Enables wrapping and extending existing CSH commands with custom Python logic. This is achieved by obtaining a reference to the original command, defining a new Python function that optionally calls the original, and then overriding the command with a `pycsh.PythonSlashCommand` instance. This allows for pre-execution checks or post-execution actions. ```python import pycsh # Get reference to original command _original_reboot = pycsh.SlashCommand("reboot") def reboot(*args: tuple[str]) -> None: # Custom logic before original command reboot_self = False if '-n' in args and len(args) > args.index('-n') + 1: if args[args.index('-n') + 1] == '0': reboot_self = True elif len(args) > 0 and args[0] == '0': reboot_self = True if reboot_self: print("Refusing to reboot self (node 0)") return # Call original command with all arguments _original_reboot(*args) # Optional: Add post-execution logic # Override the original command _reboot = pycsh.PythonSlashCommand("reboot", reboot, _original_reboot.args) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.