use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::path::PathBuf;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct PackageRequest {
pub manifest: Option<PathBuf>,
pub start_dir: Option<PathBuf>,
pub vault: Option<PathBuf>,
pub docs: Option<PathBuf>,
pub code: Option<PathBuf>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Manifest {
pub ekf_version: Option<String>,
pub name: Option<String>,
#[serde(default)]
pub partitions: Vec<PartitionManifest>,
#[serde(default)]
pub sources: SourceManifest,
#[serde(default)]
pub trust: BTreeMap<String, String>,
#[serde(default)]
pub gates: BTreeMap<String, BTreeMap<String, String>>,
#[serde(default)]
pub relations: BTreeMap<String, BTreeMap<String, String>>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct PartitionManifest {
pub id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
pub source: String,
#[serde(default)]
pub roots: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(default)]
pub languages: Vec<String>,
#[serde(default)]
pub tags: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TrustPolicy {
pub gold_ground_threshold: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stale_after_days: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agent_accepted_ttl_days: Option<u64>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RelationPolicy {
pub forward_phrase: String,
pub reverse_phrase: String,
pub context_score: i64,
pub searchable: bool,
pub traversable: bool,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub domain_kinds: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub range_kinds: Vec<String>,
}
impl RelationPolicy {
pub(crate) fn new(
forward_phrase: impl Into<String>,
reverse_phrase: impl Into<String>,
context_score: i64,
) -> Self {
Self {
forward_phrase: forward_phrase.into(),
reverse_phrase: reverse_phrase.into(),
context_score,
searchable: true,
traversable: true,
domain_kinds: Vec::new(),
range_kinds: Vec::new(),
}
}
}
impl Default for TrustPolicy {
fn default() -> Self {
Self {
gold_ground_threshold: 5,
stale_after_days: None,
agent_accepted_ttl_days: None,
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct SourceManifest {
#[serde(default)]
pub docs: Vec<String>,
#[serde(default)]
pub skills: Vec<String>,
#[serde(default)]
pub agents: Vec<String>,
#[serde(default)]
pub capabilities: Vec<String>,
#[serde(default)]
pub brief_profiles: Vec<String>,
#[serde(default)]
pub workflows: Vec<String>,
#[serde(default)]
pub evals: Vec<String>,
#[serde(default)]
pub code: Vec<CodeSource>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CodeSource {
pub path: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
#[serde(default)]
pub languages: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DiagnosticSeverity {
Info,
Warning,
Error,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EkfDiagnostic {
pub severity: DiagnosticSeverity,
pub kind: String,
pub message: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct ResolvedSources {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub vault: Option<PathBuf>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub docs: Option<PathBuf>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub code: Option<PathBuf>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub source_roots: Vec<ResolvedSourceRoot>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ResolvedSourceRoot {
pub kind: String,
pub path: PathBuf,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub partition: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub languages: Vec<String>,
pub status: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ResolvedPartition {
pub id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
pub source: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub roots: Vec<PathBuf>,
pub status: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub languages: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tags: Vec<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct PackageReport {
pub manifest_found: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub manifest_path: Option<PathBuf>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub package_root: Option<PathBuf>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub resolved: ResolvedSources,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub partitions: Vec<ResolvedPartition>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub gates: BTreeMap<String, BTreeMap<String, String>>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub gate_intents: BTreeMap<String, BTreeMap<String, GateIntent>>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub trust: BTreeMap<String, String>,
#[serde(default)]
pub trust_policy: TrustPolicy,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub relation_profiles: BTreeMap<String, RelationPolicy>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub diagnostics: Vec<EkfDiagnostic>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GateIntent {
pub capability: String,
pub signal: String,
pub description: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PackageConfig {
pub manifest: Option<Manifest>,
pub report: PackageReport,
}