progit-plugin-sdk 0.3.0

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
---@meta progit
-- SPDX-License-Identifier: LSL-1.0
-- ProGit Plugin SDK — LuaCATS type stubs for IDE autocomplete.
--
-- Plugin authors point sumneko-lua / lua-language-server at this file
-- via .luarc.json:
--
--     {
--       "Lua.workspace.library": [
--         "../progit-plugin-sdk/stubs"
--       ],
--       "Lua.diagnostics.globals": ["plugin", "context", "init"]
--     }
--
-- The runtime sandbox enforces these signatures; this file just helps
-- your editor catch typos before the plugin runs.

---@alias hook_name
---| "on_issue_created"
---| "on_issue_updated"
---| "on_issue_deleted"
---| "on_status_changed"
---| "on_sync_push"
---| "on_sync_pull"
---| "on_merge_request_created"
---| "on_external_sync"
---| "on_webhook_received"
---| "on_due_date_approaching"
---| "on_due_date_passed"
---| "on_report_requested"
---| "on_metric_query"

---@class HookFlags : table<hook_name, boolean>

---@class PluginMeta
---@field name        string  Unique plugin identifier (also the directory name).
---@field version     string  Plugin semver, e.g. "1.0.0".
---@field author      string  Author handle or organisation.
---@field description string  One-line summary.
---@field sdk_api?    string  SDK API constraint, e.g. ">=0.2". Defaults to ">=0.1.0".
---@field hooks       HookFlags
plugin = {}

---@class Issue
---@field id          string
---@field title       string
---@field description string
---@field status      string                  "backlog" | "in-progress" | "done" | ...
---@field tags        string[]
---@field assignee    string|nil
---@field effort      integer|nil             1..5
---@field blocked     boolean
---@field created     string                  ISO 8601
---@field updated     string                  ISO 8601
---@field due         string|nil              ISO 8601
---@field metadata    table<string, any>

---@class PluginContext
---@field repo_path string                    Absolute path to the active repository.
---@field user      string|nil                Current user, when known.
---@field env       table<string, string>     Environment variables exposed to the plugin.
---@field config    table<string, any>        Plugin slice of `.project/config.kdl`.
context = nil

---@class HttpResponse
---@field ok     boolean   `true` for 2xx.
---@field status integer   HTTP status code.
---@field body   string    Response body, decoded as UTF-8 text.

---@class HttpModule
---@field get    fun(url: string, headers?: table<string, string>): HttpResponse
---@field post   fun(url: string, body: string, headers?: table<string, string>): HttpResponse
---@field put    fun(url: string, body: string, headers?: table<string, string>): HttpResponse
---@field delete fun(url: string, headers?: table<string, string>): HttpResponse
---
--- Capability-gated. Requires `capabilities.network = true` in the
--- plugin manifest. If `capabilities.network_allow` is set, only those
--- hosts (suffix match) may be reached.
http = {}

---@class JsonModule
---@field encode fun(value: any): string
---@field decode fun(s: string): any
json = {}

---@class LogModule
---@field debug fun(msg: string)
---@field info  fun(msg: string)
---@field warn  fun(msg: string)
---@field error fun(msg: string)
log = {}

---@class StorageModule
---@field get    fun(key: string): any|nil          Returns the previously-set value, or nil.
---@field set    fun(key: string, value: any)       Persists value as JSON. Auto-saves on every write.
---@field delete fun(key: string): boolean          Returns whether the key existed.
---@field keys   fun(): string[]
---@field clear  fun()
---
--- Plugin-private storage scoped to `<repo>/.progit/plugins/<plugin-name>/state.json`.
--- Requires `capabilities.storage = true` in the manifest (default for
--- legacy plugins; new plugins must declare it).
storage = {}

---@class SoberRunResult
---@field ok    boolean
---@field data  table|nil
---@field error string|nil

---@class SoberModule
---@field run fun(action: string, opts?: table): SoberRunResult
---
--- Capability-gated. Requires `capabilities.sober = true` in the plugin
--- manifest and a ProGit host bridge. The host decides which actions exist;
--- `cli` is the bounded Sober argv bridge used by command contributions.
sober = {}

---@class CommandContribution
---@field name string
---@field title string|nil
---@field description string|nil
---@field entrypoint "on_command"|nil
---@field args "none"|"fixed"|"passthrough"|nil
---@field aliases string[]|nil
---@field palette boolean|nil
---@field tui table|nil
---
--- Plugins expose host-visible command endpoints through
--- `.progit-plugin.json` at `contributions.commands`. Root-level `commands`
--- is not part of the current SDK contract.

-- ── Hook signatures (informational; you implement these as global functions) ──

--- Called once after metadata extraction, before any hook fires.
--- Read `context.config` here, fail fast with `error("...")` if config is invalid.
function init() end

---@param issue Issue
---@return table  hook result; convention is `{ success = true, ... }`
function on_issue_created(issue) end

---@param issue Issue
---@return table
function on_issue_updated(issue) end

---@param data { id: string }
---@return table
function on_issue_deleted(data) end

---@param data { id: string, title: string, old_status: string, new_status: string }
---@return table
function on_status_changed(data) end

---@param data { message: string, branch: string, files_changed: integer }
---@return table  e.g. `{ allow = true, refs = { 42 } }` or `{ allow = false, message = "..." }`
function on_sync_push(data) end

---@param issues Issue[]
---@return table
function on_sync_pull(issues) end

---@param issue Issue
---@return table
function on_due_date_approaching(issue) end

---@param issue Issue
---@return table
function on_due_date_passed(issue) end

-- ── Event-style API (alternative to per-hook functions) ──

---@class PluginEvent
---@field type    string                The event variant, e.g. "IssueCreated".
---@field data    table|nil             Variant payload.

---@param event PluginEvent
---@return any|nil  return nil to indicate the plugin doesn't handle this event
function plugin.on_event(event) end