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
// SPDX-License-Identifier: LSL-1.0
// Copyright (c) 2025 Markus Maiwald

//! # ProGit Plugin SDK
//!
//! LSL-1.0 licensed SDK for building ProGit plugins in Lua or WASM.
//!
//! ## Architecture
//!
//! The SDK is the single contract between the ProGit TUI core (LCL-1.0)
//! and community / commercial plugins. The SDK itself is LSL-1.0 (file-level
//! copyleft + explicit patent grant) so corporations can ship closed plugins
//! without license contagion. Modifications to SDK files stay open.
//!
//! ## Plugin Types
//!
//! - **Lua Plugins** — lightweight scripting via LuaJIT, sandboxed by default.
//! - **WASM Plugins** — high-performance compiled plugins, available behind
//!   the `wasm` feature flag. Off by default to keep the binary lean.
//!
//! ## v0.2 Highlights
//!
//! - One canonical [`event::PluginEvent`] enum (host no longer redefines it).
//! - LuaJIT runtime is sandboxed: dangerous stdlib (`os.execute`, `io.popen`,
//!   `package.loadlib`, `debug`) is dropped by default.
//! - Per-plugin memory limits and instruction caps via [`lua::LuaPluginOptions`].
//! - Injected `log` and `storage` globals so plugins do not have to invent
//!   their own logging or persistence.
//! - Per-plugin failure isolation with quarantine after N consecutive errors.
//! - SDK API versioning + capability declarations on the plugin metadata.
//!
//! ## Example
//!
//! ```rust,ignore
//! use progit_plugin_sdk::prelude::*;
//!
//! let mut plugin = LuaPlugin::load("plugins/my-plugin.lua")?;
//! let context = PluginContext {
//!     repo_path: "/path/to/repo".into(),
//!     user: Some("developer".into()),
//!     env: Default::default(),
//!     config: Default::default(),
//! };
//! plugin.init(&context)?;
//!
//! if plugin.supports_hook(&PluginHook::OnIssueCreated) {
//!     let data = serde_json::json!({"id": "123", "title": "Bug fix"});
//!     plugin.execute_hook(&PluginHook::OnIssueCreated, &data)?;
//! }
//! # Ok::<(), anyhow::Error>(())
//! ```

pub mod contributions;
pub mod event;
pub mod lua;
pub mod manifest;
pub mod render;
pub mod storage;
pub mod traits;

#[cfg(feature = "wasm")]
pub mod wasm;

pub mod prelude {
    //! Convenience re-exports for plugin development.

    pub use crate::contributions::{
        CommandArgs, CommandContribution, CommandOutputMode, CommandTuiContribution,
        PluginContributionManifest, PluginContributions,
    };
    pub use crate::event::{PipelineJob, PipelineState, PipelineStatus, PluginEvent};
    pub use crate::lua::{
        LuaPlugin, LuaPluginOptions, SoberHost, SoberInvocation, SoberInvocationResult,
    };
    pub use crate::manifest::{Capabilities, PluginManifest, SdkVersion};
    pub use crate::render::{HighlightRequest, HighlightResponse, Rgb, TokenSpan};
    pub use crate::storage::{JsonFileStorage, PluginStorage, SyncState};
    pub use crate::traits::*;

    #[cfg(feature = "wasm")]
    pub use crate::wasm::WasmPlugin;
}

/// Plugin SDK semantic version (taken from `Cargo.toml` at build time).
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

/// SDK API contract version. Plugins declare a compatible version in their
/// metadata; the loader rejects plugins with a mismatched major.
///
/// Bump the **major** when an existing API method signature or hook payload
/// shape changes in a breaking way. Bump the **minor** when adding new
/// hooks, events, or stdlib globals.
pub const SDK_API_VERSION: &str = "0.3";

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn version_constants_are_set() {
        assert!(!VERSION.is_empty());
        assert!(SDK_API_VERSION.starts_with("0."));
    }
}