No description
Find a file
Markus Maiwald 1a68908678
feat: add event-based plugin API for query-style interactions
Extended Plugin trait with on_event() method to support event-based
plugin interactions alongside the existing hook-based system.

## Changes

### Core Trait Extension (src/traits/core.rs)
- Added on_event() method to Plugin trait
- Returns Result<Option<Value>> for optional event handling
- Enables plugins to handle structured events and return responses
- Default implementation returns Ok(None) for backward compatibility

### Lua Runtime Support (src/lua/mod.rs)
- Added call_event() method to LuaPlugin
- Invokes plugin.on_event(event) in Lua context
- Handles JSON serialization/deserialization
- Returns nil for unhandled events, response for handled ones

## Use Case

Designed for query-style plugin interactions like CI/CD status queries:
- Plugin receives structured event (e.g., PipelineStatusQuery)
- Plugin performs work (e.g., queries GitLab API)
- Plugin returns response data (e.g., pipeline status)

This complements the existing hook system for lifecycle events
(on_issue_created, etc.) with bidirectional request-response patterns.

## Backward Compatibility

Fully backward compatible:
- Existing plugins without on_event() continue working
- Default implementation returns None (event not handled)
- Hook-based system unchanged
2026-01-30 15:47:48 +01:00
docs feat: initial ProGit Plugin SDK with LuaJIT runtime 2025-12-11 01:46:56 +01:00
examples refactor: modularize traits and add plugin storage API 2026-01-15 21:50:17 +01:00
src feat: add event-based plugin API for query-style interactions 2026-01-30 15:47:48 +01:00
.gitignore feat: initial ProGit Plugin SDK with LuaJIT runtime 2025-12-11 01:46:56 +01:00
Cargo.toml refactor: modularize traits and add plugin storage API 2026-01-15 21:50:17 +01:00
CHANGELOG.md feat: initial ProGit Plugin SDK with LuaJIT runtime 2025-12-11 01:46:56 +01:00
CONTRIBUTING.md feat: initial ProGit Plugin SDK with LuaJIT runtime 2025-12-11 01:46:56 +01:00
LICENSE legal: adopt LSL-1.0 for SDK, LUL-1.0 for marketplace, add PLUGIN_LICENSING.md 2026-01-05 21:13:52 +01:00
LICENSE_MARKETPLACE legal: adopt LSL-1.0 for SDK, LUL-1.0 for marketplace, add PLUGIN_LICENSING.md 2026-01-05 21:13:52 +01:00
LICENSE_VENTURE legal: adopt LSL-1.0 for SDK, LUL-1.0 for marketplace, add PLUGIN_LICENSING.md 2026-01-05 21:13:52 +01:00
PLUGIN_LICENSING.md legal: adopt LSL-1.0 for SDK, LUL-1.0 for marketplace, add PLUGIN_LICENSING.md 2026-01-05 21:13:52 +01:00
README.md legal: adopt LSL-1.0 for SDK, LUL-1.0 for marketplace, add PLUGIN_LICENSING.md 2026-01-05 21:13:52 +01:00
SETUP_COMPLETE.md feat: initial ProGit Plugin SDK with LuaJIT runtime 2025-12-11 01:46:56 +01:00

ProGit Plugin SDK

License Crates.io

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 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

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

use progit_plugin_sdk::prelude::*;

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

Plugin Structure

Lua Plugin Template

-- 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/ 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

Run examples:

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:

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:

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

Issue Schema

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

# 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.

git clone https://git.maiwald.work/SSSS/progit-plugin-sdk
cd progit-plugin-sdk
cargo test
cargo fmt

License: LSL-1.0 (Sovereign)


License

Copyright (c) 2025 Markus Maiwald

Licensed under the Libertaria Sovereign License, Version 1.0. See LICENSE for details.

Plugin authors: You may license your plugins under ANY terms. See PLUGIN_LICENSING.md.


Made with 🔥 by developers, for developers.