Skip to main content

navi_plugin_api/
lib.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::sync::Arc;
4
5pub const NAVI_PLUGIN_API_VERSION: u32 = 2;
6pub const NAVI_PLUGIN_ENTRYPOINT: &[u8] = b"navi_plugin_entrypoint";
7
8pub type PluginCreate = unsafe fn() -> Box<dyn NaviPlugin>;
9
10pub trait NaviPlugin: Send + Sync {
11    fn metadata(&self) -> PluginMetadata;
12    fn register(&self, registry: &mut dyn PluginRegistry) -> Result<(), String>;
13}
14
15pub trait PluginRegistry {
16    fn register_tool(&mut self, tool: Arc<dyn PluginTool>);
17    fn register_agent_policy(&mut self, name: &str);
18    fn register_tui_component(&mut self, name: &str);
19}
20
21/// A TUI component that a plugin can register to render custom UI regions.
22///
23/// This trait is only available when the `tui` feature is enabled, which
24/// brings in the `copland` framework dependency. Plugins that only need
25/// tools can ignore this trait entirely.
26#[cfg(feature = "tui")]
27pub trait TuiComponent: Send + Sync {
28    /// Unique identifier for this component.
29    fn id(&self) -> &str;
30
31    /// Render the component into the given area.
32    fn render(
33        &mut self,
34        frame: &mut copland::ratatui::Frame,
35        area: copland::ratatui::layout::Rect,
36        ctx: &dyn copland::panel::PanelContext,
37    );
38
39    /// Handle a key event.
40    fn handle_key(
41        &mut self,
42        key: &copland::crossterm::event::KeyEvent,
43        ctx: &dyn copland::panel::PanelContext,
44    ) -> copland::keymap::KeyOutcome {
45        let _ = (key, ctx);
46        copland::keymap::KeyOutcome::Ignored
47    }
48
49    /// Preferred size for layout.
50    fn preferred_size(&self) -> copland::panel::PanelSize {
51        copland::panel::PanelSize::Flex
52    }
53
54    /// Whether this component should be visible.
55    fn is_visible(&self) -> bool {
56        true
57    }
58
59    /// Z-order for overlapping components.
60    fn z_order(&self) -> i16 {
61        0
62    }
63}
64
65/// Extension trait for PluginRegistry to register TUI components.
66#[cfg(feature = "tui")]
67pub trait PluginRegistryTui {
68    fn register_tui_panel(&mut self, component: Box<dyn TuiComponent>);
69}
70
71/// Self-contained tool trait for plugins. Does not depend on navi-core types.
72/// Plugin authors implement this trait; the host adapts it to `navi_core::Tool`.
73pub trait PluginTool: Send + Sync {
74    fn definition(&self) -> PluginToolDefinition;
75    fn invoke(&self, invocation: PluginToolInvocation) -> Result<PluginToolResult, String>;
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct PluginToolDefinition {
80    pub name: String,
81    pub description: String,
82    pub kind: PluginToolKind,
83    #[serde(default)]
84    pub input_schema: Value,
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
88pub enum PluginToolKind {
89    Read,
90    Write,
91    Command,
92    Custom,
93}
94
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
96pub struct PluginToolInvocation {
97    pub id: String,
98    pub tool_name: String,
99    pub input: Value,
100}
101
102#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
103pub struct PluginToolResult {
104    pub invocation_id: String,
105    pub ok: bool,
106    pub output: Value,
107}
108
109#[derive(Debug, Clone)]
110pub struct PluginMetadata {
111    pub name: String,
112    pub version: String,
113    pub api_version: u32,
114    pub capabilities: Vec<PluginCapability>,
115}
116
117#[derive(Debug, Clone)]
118pub enum PluginCapability {
119    FileSystem,
120    Shell,
121    Network,
122    Tui,
123    Model,
124    Session,
125}