Update release version to v0.1.2.b.5 in index.html and version.txt
This commit is contained in:
355
PLUGINS.md
Normal file
355
PLUGINS.md
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
# 📘 **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 Python’s 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
|
||||||
|
✔ Don’t 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
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
<div class="hero__metrics">
|
<div class="hero__metrics">
|
||||||
<div class="metric">
|
<div class="metric">
|
||||||
<p class="metric__label">Current release</p>
|
<p class="metric__label">Current release</p>
|
||||||
<p class="metric__value">v0.1.2.b.4</p>
|
<p class="metric__value">v0.1.2.b.5</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="metric">
|
<div class="metric">
|
||||||
<p class="metric__label">Supported families</p>
|
<p class="metric__label">Supported families</p>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0.1.2.b.4
|
0.1.2.b.5
|
||||||
Reference in New Issue
Block a user