1use serde::{Deserialize, Serialize};
2use std::collections::BTreeMap;
3use std::path::PathBuf;
4
5#[derive(Debug, Clone, Default, PartialEq, Eq)]
6pub struct PackageRequest {
7 pub manifest: Option<PathBuf>,
8 pub start_dir: Option<PathBuf>,
9 pub vault: Option<PathBuf>,
10 pub docs: Option<PathBuf>,
11 pub code: Option<PathBuf>,
12}
13
14#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
15pub struct Manifest {
16 pub ekf_version: Option<String>,
17 pub name: Option<String>,
18 #[serde(default)]
19 pub partitions: Vec<PartitionManifest>,
20 #[serde(default)]
21 pub sources: SourceManifest,
22 #[serde(default)]
23 pub trust: BTreeMap<String, String>,
24 #[serde(default)]
25 pub gates: BTreeMap<String, BTreeMap<String, String>>,
26 #[serde(default)]
27 pub relations: BTreeMap<String, BTreeMap<String, String>>,
28}
29
30#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
31pub struct PartitionManifest {
32 pub id: String,
33 #[serde(default, skip_serializing_if = "Option::is_none")]
34 pub title: Option<String>,
35 pub source: String,
36 #[serde(default)]
37 pub roots: Vec<String>,
38 #[serde(default, skip_serializing_if = "Option::is_none")]
39 pub role: Option<String>,
40 #[serde(default)]
41 pub languages: Vec<String>,
42 #[serde(default)]
43 pub tags: Vec<String>,
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
47pub struct TrustPolicy {
48 pub gold_ground_threshold: u32,
49 #[serde(default, skip_serializing_if = "Option::is_none")]
50 pub stale_after_days: Option<u64>,
51 #[serde(default, skip_serializing_if = "Option::is_none")]
52 pub agent_accepted_ttl_days: Option<u64>,
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
56pub struct RelationPolicy {
57 pub forward_phrase: String,
58 pub reverse_phrase: String,
59 pub context_score: i64,
60 pub searchable: bool,
61 pub traversable: bool,
62 #[serde(default, skip_serializing_if = "Vec::is_empty")]
63 pub domain_kinds: Vec<String>,
64 #[serde(default, skip_serializing_if = "Vec::is_empty")]
65 pub range_kinds: Vec<String>,
66}
67
68impl RelationPolicy {
69 pub(crate) fn new(
70 forward_phrase: impl Into<String>,
71 reverse_phrase: impl Into<String>,
72 context_score: i64,
73 ) -> Self {
74 Self {
75 forward_phrase: forward_phrase.into(),
76 reverse_phrase: reverse_phrase.into(),
77 context_score,
78 searchable: true,
79 traversable: true,
80 domain_kinds: Vec::new(),
81 range_kinds: Vec::new(),
82 }
83 }
84}
85
86impl Default for TrustPolicy {
87 fn default() -> Self {
88 Self {
89 gold_ground_threshold: 5,
90 stale_after_days: None,
91 agent_accepted_ttl_days: None,
92 }
93 }
94}
95
96#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
97pub struct SourceManifest {
98 #[serde(default)]
99 pub docs: Vec<String>,
100 #[serde(default)]
101 pub skills: Vec<String>,
102 #[serde(default)]
103 pub agents: Vec<String>,
104 #[serde(default)]
105 pub capabilities: Vec<String>,
106 #[serde(default)]
107 pub brief_profiles: Vec<String>,
108 #[serde(default)]
109 pub workflows: Vec<String>,
110 #[serde(default)]
111 pub evals: Vec<String>,
112 #[serde(default)]
113 pub code: Vec<CodeSource>,
114}
115
116#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
117pub struct CodeSource {
118 pub path: String,
119 #[serde(default, skip_serializing_if = "Option::is_none")]
120 pub source: Option<String>,
121 #[serde(default)]
122 pub languages: Vec<String>,
123}
124
125#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
126#[serde(rename_all = "snake_case")]
127pub enum DiagnosticSeverity {
128 Info,
129 Warning,
130 Error,
131}
132
133#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
134pub struct EkfDiagnostic {
135 pub severity: DiagnosticSeverity,
136 pub kind: String,
137 pub message: String,
138 #[serde(default, skip_serializing_if = "Option::is_none")]
139 pub source: Option<String>,
140}
141
142#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
143pub struct ResolvedSources {
144 #[serde(default, skip_serializing_if = "Option::is_none")]
145 pub vault: Option<PathBuf>,
146 #[serde(default, skip_serializing_if = "Option::is_none")]
147 pub docs: Option<PathBuf>,
148 #[serde(default, skip_serializing_if = "Option::is_none")]
149 pub code: Option<PathBuf>,
150 #[serde(default, skip_serializing_if = "Vec::is_empty")]
151 pub source_roots: Vec<ResolvedSourceRoot>,
152}
153
154#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
155pub struct ResolvedSourceRoot {
156 pub kind: String,
157 pub path: PathBuf,
158 #[serde(default, skip_serializing_if = "Option::is_none")]
159 pub partition: Option<String>,
160 #[serde(default, skip_serializing_if = "Vec::is_empty")]
163 pub languages: Vec<String>,
164 pub status: String,
168}
169
170#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
171pub struct ResolvedPartition {
172 pub id: String,
173 #[serde(default, skip_serializing_if = "Option::is_none")]
174 pub title: Option<String>,
175 pub source: String,
176 #[serde(default, skip_serializing_if = "Option::is_none")]
177 pub role: Option<String>,
178 #[serde(default, skip_serializing_if = "Vec::is_empty")]
179 pub roots: Vec<PathBuf>,
180 pub status: String,
181 #[serde(default, skip_serializing_if = "Vec::is_empty")]
182 pub languages: Vec<String>,
183 #[serde(default, skip_serializing_if = "Vec::is_empty")]
184 pub tags: Vec<String>,
185}
186
187#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
188pub struct PackageReport {
189 pub manifest_found: bool,
190 #[serde(default, skip_serializing_if = "Option::is_none")]
191 pub manifest_path: Option<PathBuf>,
192 #[serde(default, skip_serializing_if = "Option::is_none")]
193 pub package_root: Option<PathBuf>,
194 #[serde(default, skip_serializing_if = "Option::is_none")]
195 pub name: Option<String>,
196 pub resolved: ResolvedSources,
197 #[serde(default, skip_serializing_if = "Vec::is_empty")]
198 pub partitions: Vec<ResolvedPartition>,
199 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
200 pub gates: BTreeMap<String, BTreeMap<String, String>>,
201 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
202 pub gate_intents: BTreeMap<String, BTreeMap<String, GateIntent>>,
203 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
204 pub trust: BTreeMap<String, String>,
205 #[serde(default)]
206 pub trust_policy: TrustPolicy,
207 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
208 pub relation_profiles: BTreeMap<String, RelationPolicy>,
209 #[serde(default, skip_serializing_if = "Vec::is_empty")]
210 pub diagnostics: Vec<EkfDiagnostic>,
211}
212
213#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
214pub struct GateIntent {
215 pub capability: String,
216 pub signal: String,
217 pub description: String,
218}
219
220#[derive(Debug, Clone, PartialEq, Eq)]
221pub struct PackageConfig {
222 pub manifest: Option<Manifest>,
223 pub report: PackageReport,
224}