Skip to main content

rightkit_agent_engine_api_integrations/
plugin_manifest.rs

1//! Portable plugin path & manifest projections.
2
3use crate::plugin_signature::{read_record, SignatureStatus};
4use std::path::{Path, PathBuf};
5
6pub fn default_plugin_dir() -> PathBuf {
7    // An explicit directory is already the catalog root; only home-derived
8    // defaults need the plugins suffix.
9    if let Some(dir) = std::env::var_os(rightkit_agent_config::env_name("PLUGIN_DIR")) {
10        return PathBuf::from(dir);
11    }
12    // No fallback location: a missing state root fails, it never redirects plugins into the
13    // working directory.
14    rightkit_agent_config::state_root()
15        .unwrap_or_else(|| {
16            eprintln!("rightkit: cannot continue without a state directory; refusing to fall back");
17            std::process::exit(2)
18        })
19        .join("plugins")
20}
21
22pub fn plugin_manifest_json(
23    manifest: &rightkit_agent_plugins::PluginManifest,
24) -> serde_json::Value {
25    serde_json::json!({
26        "id": manifest.id,
27        "name": manifest.name,
28        "version": manifest.version,
29        "description": manifest.description,
30        "entry": manifest.entry,
31        "providesTools": manifest.provides_tools,
32        "providesCommands": manifest.provides_commands,
33        "tools": manifest.tools,
34        "commands": manifest.commands,
35        "prompts": manifest.prompts,
36        "middleware": manifest.middleware,
37        "sandbox": manifest.sandbox,
38        "enabled": manifest.enabled,
39    })
40}
41
42/// Where the plugin marketplace file lives; rightkit-agent-server's marketplace routes read it.
43pub fn default_plugin_marketplace_path() -> PathBuf {
44    std::env::var_os("RIGHTKIT_PLUGIN_MARKETPLACE")
45        .map(PathBuf::from)
46        .or_else(|| rightkit_agent_config::state_root().map(|root| root.join("marketplace.json")))
47        .unwrap_or_else(|| {
48            std::env::current_dir()
49                .unwrap_or_else(|_| PathBuf::from("."))
50                .join(".rightkit")
51                .join("marketplace.json")
52        })
53}
54
55/// A plugin manifest as JSON with its recorded signature status and signer (rightkit-agent-server plugin routes).
56pub fn plugin_manifest_json_with_provenance(
57    manifest: &rightkit_agent_plugins::PluginManifest,
58    install_dir: &Path,
59) -> serde_json::Value {
60    let mut value = plugin_manifest_json(manifest);
61    let record = read_record(install_dir);
62    let status = match record.status {
63        SignatureStatus::Signed => "signed",
64        SignatureStatus::Unsigned => "unsigned",
65        SignatureStatus::Unknown => "unknown",
66    };
67    if let Some(object) = value.as_object_mut() {
68        object.insert(
69            "signatureStatus".into(),
70            serde_json::Value::String(status.into()),
71        );
72        object.insert(
73            "signatureSignedBy".into(),
74            serde_json::Value::String(record.signed_by),
75        );
76    }
77    value
78}