warble_claude_code/
manifest.rs1use crate::ir::{ComponentNode, WarbleIr};
12use serde::Serialize;
13
14pub const MANIFEST_VERSION: &str = "0.1";
15
16#[derive(Debug, Serialize)]
17pub struct RenderContract {
18 pub blocks: Vec<String>,
19}
20
21#[derive(Debug, Serialize)]
22pub struct ManifestContext {
23 pub project: String,
24 pub binding_mode: String,
25 pub precondition: String,
26}
27
28#[derive(Debug, Serialize)]
29pub struct ManifestComponent {
30 pub verb: String,
31 #[serde(rename = "type")]
32 pub component_type: String,
33 pub realization_kind: String,
34 pub context: ManifestContext,
35 pub trigger: String,
36 pub outcome: String,
37 pub required_capabilities: Vec<String>,
38 pub render_contract: Option<RenderContract>,
40}
41
42#[derive(Debug, Serialize)]
43pub struct CapabilityManifest {
44 pub warble_manifest_version: String,
45 pub profile: String,
46 pub components: Vec<ManifestComponent>,
47}
48
49fn manifest_component(node: &ComponentNode) -> ManifestComponent {
50 let block_types: Vec<String> = node
51 .effect
52 .render_blocks
53 .iter()
54 .map(|b| b.block_type.clone())
55 .collect();
56 ManifestComponent {
57 verb: node.verb.clone(),
58 component_type: node.component_type.as_str().to_string(),
59 realization_kind: node.realization_kind.as_str().to_string(),
60 context: ManifestContext {
61 project: node.context_binding.project.clone(),
62 binding_mode: node.context_binding.binding_mode.clone(),
63 precondition: node.precondition_result.status.clone(),
64 },
65 trigger: node.trigger.kind.as_str().to_string(),
66 outcome: node.effect.outcome.kind.as_str().to_string(),
67 required_capabilities: node.required_capabilities.clone(),
68 render_contract: if block_types.is_empty() {
69 None
70 } else {
71 Some(RenderContract {
72 blocks: block_types,
73 })
74 },
75 }
76}
77
78pub fn build_manifest(ir: &WarbleIr) -> CapabilityManifest {
80 CapabilityManifest {
81 warble_manifest_version: MANIFEST_VERSION.to_string(),
82 profile: ir.profile.clone(),
83 components: ir.components.iter().map(manifest_component).collect(),
84 }
85}