Files
ZDTT/PLUGINS.md

355 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 📘 **ZDTT Plugin Development Guide**
*Create safe, powerful extensions for the ZDTT Terminal.*
---
## 🟦 Introduction
ZDTT supports a secure, sandboxed plugin system that allows developers to extend the terminal with custom commands.
Plugins live inside:
```
~/.zdtt/plugins/
```
A plugin is simply a Python file that:
1. Contains **no top-level executable code**
2. Defines functions or classes
3. Defines a mandatory function:
```python
def register_commands():
return { "command": callable }
```
Plugins are automatically loaded when ZDTT starts or when you run:
```
plugins reload
```
---
# 🛡️ Plugin Security Model
ZDTT has strict safety validation to protect users from malicious plugins.
Every plugin must pass **six security layers**:
---
## **1. AST Validation**
At load time, ZDTT parses the plugin using Pythons AST.
Allowed at the top level:
* Imports
* From-imports
* Function definitions
* Class definitions
* A file-level docstring
Forbidden (**causes quarantine**):
* Print statements
* Assignments
* Function calls
* Loops
* Try/except blocks
* Any executable code
* Anything that runs automatically
Example of an unsafe plugin:
```python
print("hacked!") # ❌ this will be quarantined
os.system("rm -rf /") # ❌ also quarantined
```
Unsafe plugins are moved to:
```
~/.zdtt/quarantine/
```
---
## **2. Import Trust Prompt**
Plugins may import modules:
```python
import os
import subprocess
```
However:
**Any plugin with imports triggers a trust confirmation.**
If the user does **not** trust the plugin, it is quarantined.
If the user approves, the plugin name is added to:
```
config.json → trusted_plugins
```
Only trusted plugins may use `__import__`.
---
## **3. Sandboxed Execution**
Plugins run inside a restricted environment:
* Only safe builtins are exposed
* Dangerous builtins (like `exec` or `eval`) are blocked
* Imports only work for trusted plugins
* Code cannot escape the sandbox
---
## **4. register_commands() Validation**
Every plugin must define:
```python
def register_commands():
return {"name": function}
```
ZDTT verifies:
* The function exists
* The return value is a dict
* All values are callable
* Command names are valid strings
---
## **5. Protected Command Names**
Plugins **cannot override** important commands such as:
```
ssh, sudo, su, cp, mv, rm, ls, cat,
chmod, chown, history, zps, zdtt,
pip, python, python3, curl, wget
```
Attempting to override them causes quarantine.
---
## **6. Runtime Registration**
Once the plugin passes all previous checks, ZDTT adds its commands to the shell environment.
Example:
```python
{
"weather": cmd_weather,
"hello": cmd_hello
}
```
These appear in autocomplete and `help`.
---
# 🟩 Plugin Structure
A minimal valid plugin:
```python
"""
My Plugin
"""
def cmd_test(args):
print("Hello from ZDTT plugin!")
def register_commands():
return {"test": cmd_test}
```
---
# 🟧 Arguments
ZDTT passes command arguments as a list.
Example:
```
hello world how are you
```
Results in:
```python
cmd_hello(["world", "how", "are", "you"])
```
---
# 🟪 Example Plugin (Official)
From `example_plugin.py`:
```python
"""
Example ZDTT Plugin
"""
import subprocess
import os
def cmd_hello(args):
...
def cmd_weather(args):
...
def cmd_sysinfo(args):
...
def register_commands():
return {
"hello": cmd_hello,
"weather": cmd_weather,
"sysinfo": cmd_sysinfo
}
```
All three commands use argument lists exactly as ZDTT passes them.
---
# 🟫 Installing Plugins
### **Manual Install**
Place plugin file in:
```
~/.zdtt/plugins/
```
Then reload:
```
plugins reload
```
---
### **Install via ZPS**
Install directly from a URL:
```
zps install https://raw.githubusercontent.com/user/repo/plugin.py
```
ZPS will:
* Download the file
* Save it to your plugin directory
* Warn if it already exists
* Ask if you trust imports (if any)
---
# 🟨 Debugging Plugins
ZDTT logs plugin errors to:
```
~/.zdtt/plugin_errors.log
```
Quarantined plugins appear in:
```
~/.zdtt/quarantine/
```
Reload plugins:
```
plugins reload
```
---
# 🟩 Best Practices for Plugin Developers
✔ Wrap all code inside functions
✔ Avoid imports unless required
✔ Validate arg lists
✔ Use try/except around risky operations
✔ Keep commands short and simple
✔ Document your commands
✔ Never modify global state
✔ Dont override protected commands
---
# 🟦 Advanced Plugin Tips
### Show usage/help
```python
def cmd_calc(args):
"""Usage: calc <expression>"""
...
```
ZDTT automatically pulls these docstrings into the `help` system.
### Combine args into a string
```python
expr = " ".join(args)
```
### Use subprocess safely
```python
try:
subprocess.run(["ls"])
except Exception as e:
print("Error:", e)
```
### Read files safely
Use try/except to avoid crashing the shell.
---
# 🟣 Full Plugin Template
```python
"""
Plugin Name: <your plugin>
Description: <what it does>
Author: <you>
"""
# Optional imports (will require trust prompt)
import subprocess
def cmd_example(args):
print("Example plugin working!")
def register_commands():
return {
"example": cmd_example
}
```