mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-30 23:14:37 +00:00
* refactor: remove mobile platform support and update documentation - Updated CONTRIBUTING.md and SECURITY.md to reflect the removal of Android and iOS support, focusing on desktop platforms only. - Modified AGENTS.md and MEMORY.md to clarify the platform capabilities of OpenHuman as a desktop application. - Adjusted various Rust files to eliminate references to mobile platforms, including socket management and platform detection logic. - Removed mobile-specific code from SkillsGrid and Skills components, ensuring the application is tailored for desktop usage. - Deleted unused iOS and Android assets and configurations from the Tauri project structure. * chore: remove zeroclaw mentions and mobile support paths
127 lines
4.2 KiB
Rust
127 lines
4.2 KiB
Rust
//! Skill manifest parsing.
|
|
//!
|
|
//! Each skill directory contains a `manifest.json` describing the skill.
|
|
//! This module parses it and produces a `SkillConfig` for the runtime engine.
|
|
|
|
use crate::runtime::types::SkillConfig;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::path::Path;
|
|
|
|
/// Setup configuration from manifest.json.
|
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
|
pub struct SkillSetup {
|
|
#[serde(default)]
|
|
pub required: bool,
|
|
pub label: Option<String>,
|
|
/// OAuth configuration (provider, scopes, apiBaseUrl).
|
|
pub oauth: Option<serde_json::Value>,
|
|
}
|
|
|
|
/// Raw manifest as it appears on disk.
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct SkillManifest {
|
|
/// Unique skill identifier (e.g., "price-tracker").
|
|
pub id: String,
|
|
/// Human-readable name.
|
|
pub name: String,
|
|
/// Runtime type. Supported values: "v8", "javascript".
|
|
#[serde(default = "default_runtime")]
|
|
pub runtime: String,
|
|
/// Entry point JS file relative to the skill directory.
|
|
#[serde(default = "default_entry_point")]
|
|
pub entry: String,
|
|
/// Memory limit in MB (optional, default 64).
|
|
pub memory_limit_mb: Option<usize>,
|
|
/// Whether to auto-start on app launch.
|
|
#[serde(default)]
|
|
pub auto_start: bool,
|
|
/// Version string (informational).
|
|
pub version: Option<String>,
|
|
/// Whether to ignore in production.
|
|
#[serde(default)]
|
|
pub ignoreInProduction: bool,
|
|
/// Description (informational).
|
|
pub description: Option<String>,
|
|
/// Setup configuration (optional).
|
|
#[serde(default)]
|
|
pub setup: Option<SkillSetup>,
|
|
/// Platform filter. When present, only these platforms will load the skill.
|
|
/// Valid values: "windows", "macos", "linux".
|
|
/// When absent or empty, the skill is available on all platforms.
|
|
#[serde(default)]
|
|
pub platforms: Option<Vec<String>>,
|
|
/// Skill type for the unified registry dispatch.
|
|
/// "openhuman" → executed via QuickJS runtime (default).
|
|
/// "openclaw" → loaded and executed from SKILL.md/SKILL.toml.
|
|
#[serde(default = "default_skill_type")]
|
|
pub skill_type: String,
|
|
}
|
|
|
|
fn default_skill_type() -> String {
|
|
"openhuman".to_string()
|
|
}
|
|
|
|
fn default_runtime() -> String {
|
|
"v8".to_string()
|
|
}
|
|
|
|
fn default_entry_point() -> String {
|
|
"index.js".to_string()
|
|
}
|
|
|
|
/// Returns the current platform as a manifest-compatible string.
|
|
fn current_platform() -> &'static str {
|
|
match std::env::consts::OS {
|
|
"windows" => "windows",
|
|
"macos" => "macos",
|
|
"linux" => "linux",
|
|
_ => "unknown",
|
|
}
|
|
}
|
|
|
|
impl SkillManifest {
|
|
/// Parse a manifest from a JSON string.
|
|
pub fn from_json(json: &str) -> Result<Self, String> {
|
|
serde_json::from_str(json).map_err(|e| format!("Failed to parse manifest: {e}"))
|
|
}
|
|
|
|
/// Read and parse a manifest from disk.
|
|
pub async fn from_path(path: &Path) -> Result<Self, String> {
|
|
let content = tokio::fs::read_to_string(path)
|
|
.await
|
|
.map_err(|e| format!("Failed to read manifest at {}: {e}", path.display()))?;
|
|
Self::from_json(&content)
|
|
}
|
|
|
|
/// Whether this manifest declares a JavaScript runtime (QuickJS).
|
|
/// Accepts "v8", "javascript", "quickjs" for compatibility.
|
|
pub fn is_javascript(&self) -> bool {
|
|
matches!(self.runtime.as_str(), "v8" | "javascript" | "quickjs")
|
|
}
|
|
|
|
/// Whether the skill is available on the current platform.
|
|
/// Returns true when `platforms` is absent or empty (available everywhere).
|
|
pub fn supports_current_platform(&self) -> bool {
|
|
let platforms = match &self.platforms {
|
|
Some(p) if !p.is_empty() => p,
|
|
_ => return true, // No restriction → available everywhere
|
|
};
|
|
let current = current_platform();
|
|
platforms.iter().any(|p| p == current)
|
|
}
|
|
|
|
/// Convert to a SkillConfig for the runtime engine.
|
|
pub fn to_config(&self) -> SkillConfig {
|
|
SkillConfig {
|
|
skill_id: self.id.clone(),
|
|
name: self.name.clone(),
|
|
entry_point: self.entry.clone(),
|
|
memory_limit: self
|
|
.memory_limit_mb
|
|
.map(|mb| mb * 1024 * 1024)
|
|
.unwrap_or(64 * 1024 * 1024),
|
|
auto_start: self.auto_start,
|
|
}
|
|
}
|
|
}
|