progit-plugin-sdk 0.2.1

Plugin SDK for ProGit β€” sandboxed LuaJIT runtime with capability-based security. LSL-1.0 (file-level copyleft, proprietary plugins allowed via the commercial bridge).
Documentation
# ProGit Plugin SDK

[![License](https://img.shields.io/badge/License-LSL--1.0-green.svg)](LICENSE)
[![Crates.io](https://img.shields.io/crates/v/progit-plugin-sdk.svg)](https://crates.io/crates/progit-plugin-sdk)

**LSL-1.0 licensed SDK for building ProGit plugins in Lua or WASM.**

## Why LSL-1.0 (Sovereign)?

This SDK is intentionally licensed under **LSL-1.0** (file-level copyleft) to:

- **Allow proprietary plugins** - Your app code stays yours
- **Protect the engine** - Modifications to SDK files must be shared back
- **Patent disarmament** - "Cold War" clause for mutual protection
- **Legal certainty** - Governed by Dutch Law (Amsterdam)

The ProGit TUI core uses LCL-1.0 (strong copyleft). **Your plugins do NOT inherit this** because they link to the SDK, not the Core.

See [PLUGIN_LICENSING.md](PLUGIN_LICENSING.md) for details.

---

## Features

- πŸ¦€ **Rust-native** - Type-safe plugin trait system
- πŸŒ™ **Lua support** - Lightweight scripting for simple integrations
- πŸ•ΈοΈ **WASM support** - High-performance compiled plugins with sandboxing
- πŸ”Œ **Hook system** - Issue lifecycle, sync, merge requests, custom commands
- πŸ›‘οΈ **Sandboxed** - Plugins run in isolated environments
- πŸ“¦ **Zero dependencies** on ProGit core - Clean separation

---

## Quick Start

### Lua Plugin

```rust
use progit_plugin_sdk::prelude::*;

let script = r#"
    plugin = {
        name = "hello-world",
        version = "1.0.0",
        author = "Your Name",
        hooks = {
            on_issue_created = true,
        }
    }
    
    function on_issue_created(issue)
        print("New issue: " .. issue.title)
        return { success = true }
    end
"#;

let mut plugin = LuaPlugin::from_string(script, "hello")?;
plugin.on_issue_created(&issue)?;
```

### WASM Plugin

```rust
use progit_plugin_sdk::prelude::*;

let plugin = WasmPlugin::load("plugins/my_plugin.wasm")?;
plugin.on_issue_created(&issue)?;
```

---

## Plugin Structure

### Lua Plugin Template

```lua
-- SPDX-License-Identifier: Apache-2.0

plugin = {
    name = "my-plugin",
    version = "1.0.0",
    author = "Your Name",
    description = "Plugin description",
    hooks = {
        on_issue_created = true,
        on_issue_updated = true,
    }
}

function init()
    -- Called once when plugin loads
    print("Plugin initialized!")
end

function on_issue_created(issue)
    -- Called when an issue is created
    print("New issue: " .. issue.title)
    return { success = true }
end

function on_issue_updated(issue)
    -- Called when an issue is updated
    return { success = true }
end
```

### WASM Plugin Template

See [`examples/wasm_plugin_template/`](examples/wasm_plugin_template/) for a complete Rust β†’ WASM plugin example.

---

## Available Hooks

| Hook | Trigger | Data |
|------|---------|------|
| `on_issue_created` | Issue created | `Issue` |
| `on_issue_updated` | Issue updated | `Issue` |
| `on_issue_deleted` | Issue deleted | `{ id: string }` |
| `on_status_changed` | Issue status changed | `Issue` |
| `on_sync_push` | Before sync push | `Issue[]` |
| `on_sync_pull` | After sync pull | `Issue[]` |
| `on_merge_request_created` | MR created | `MergeRequest` |
| `on_command(name)` | Custom command | Custom |

---

## Examples

- [`examples/lua_hello_world.rs`]examples/lua_hello_world.rs - Basic Lua plugin
- [`examples/jira_sync.lua`]examples/jira_sync.lua - Sync issues to Jira
- [`examples/wasm_hello_world.rs`]examples/wasm_hello_world.rs - Basic WASM plugin

Run examples:

```bash
cargo run --example lua_hello_world
```

---

## Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ProGit TUI Core (Rust)                                      β”‚
β”‚  LCL-1.0 Licensed (Strong Copyleft)                          β”‚
β”‚  NO proprietary code linked                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                   progit-plugin-sdk (LSL-1.0)
                            β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Community Plugins (Lua/WASM)                                β”‚
β”‚  ANY License (LCL/LSL/LUL/LVL or Proprietary)                β”‚
β”‚  Loaded at RUNTIME via SDK                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

**Key Points:**

- SDK is **LSL-1.0** - "Commercial Bridge" allows proprietary plugins
- ProGit core is **LCL-1.0** - strong copyleft, source always visible
- No static linking - plugins loaded at runtime
- Clean API boundary - zero license contagion for your code

---

## Plugin Context

Plugins receive a `PluginContext` on initialization:

```rust
pub struct PluginContext {
    pub repo_path: String,
    pub user: Option<String>,
    pub env: HashMap<String, String>,
    pub config: HashMap<String, serde_json::Value>,
}
```

Access in Lua:

```lua
function init()
    print("Repository: " .. context.repo_path)
    print("User: " .. (context.user or "unknown"))
end
```

---

## Issue Schema

```rust
pub struct Issue {
    pub id: String,
    pub title: String,
    pub description: String,
    pub status: String,              // "backlog" | "in-progress" | "done"
    pub tags: Vec<String>,
    pub assignee: Option<String>,
    pub effort: Option<u8>,          // 1-5
    pub blocked: bool,
    pub created: String,             // ISO 8601
    pub updated: String,             // ISO 8601
    pub due: Option<String>,         // ISO 8601
    pub metadata: HashMap<String, serde_json::Value>,
}
```

---

## Building Plugins

### Lua Plugins

Just write `.lua` files! No build step required.

### WASM Plugins

```bash
# Install WASM target
rustup target add wasm32-wasi

# Build your plugin
cd my-plugin
cargo build --target wasm32-wasi --release

# Plugin is at: target/wasm32-wasi/release/my_plugin.wasm
```

---

## Contributing

Built with ❀️ in **Rust**.

```bash
git clone https://git.sovereign-society.org/ProGit/progit-plugin-sdk
cd progit-plugin-sdk
cargo test
cargo fmt
```

**License:** [LSL-1.0 (Sovereign)](LICENSE)

---

## License

Copyright (c) 2025 Markus Maiwald

Licensed under the Libertaria Sovereign License, Version 1.0.
See [LICENSE](LICENSE) for details.

**Plugin authors:** You may license your plugins under ANY terms. See [PLUGIN_LICENSING.md](PLUGIN_LICENSING.md).

---

**Made with πŸ”₯ by developers, for developers.**