plexus_substrate/
builder.rs1use std::sync::{Arc, Weak};
6
7use crate::activations::arbor::{Arbor, ArborConfig};
8use crate::activations::bash::Bash;
9use crate::activations::changelog::{Changelog, ChangelogStorageConfig};
10use crate::activations::claudecode::{ClaudeCode, ClaudeCodeStorage, ClaudeCodeStorageConfig};
11use crate::activations::claudecode_loopback::{ClaudeCodeLoopback, LoopbackStorageConfig};
12use crate::activations::cone::{Cone, ConeStorageConfig};
13use crate::activations::echo::Echo;
14use crate::activations::health::Health;
15use crate::activations::interactive::Interactive;
16use crate::activations::mustache::{Mustache, MustacheStorageConfig};
17use crate::activations::solar::Solar;
18use crate::plexus::DynamicHub;
19use registry::Registry;
21
22pub async fn build_plexus_rpc() -> Arc<DynamicHub> {
40 let arbor: Arbor<Weak<DynamicHub>> = Arbor::with_context_type(ArborConfig::default())
43 .await
44 .expect("Failed to initialize Arbor");
45 let arbor_storage = arbor.storage();
46
47 let cone: Cone<Weak<DynamicHub>> = Cone::with_context_type(ConeStorageConfig::default(), arbor_storage.clone())
50 .await
51 .expect("Failed to initialize Cone");
52
53 let claudecode_storage = ClaudeCodeStorage::new(
56 ClaudeCodeStorageConfig::default(),
57 arbor_storage,
58 )
59 .await
60 .expect("Failed to initialize ClaudeCode storage");
61 let claudecode: ClaudeCode<Weak<DynamicHub>> = ClaudeCode::with_context_type(Arc::new(claudecode_storage));
62
63 let mustache = Mustache::new(MustacheStorageConfig::default())
65 .await
66 .expect("Failed to initialize Mustache");
67
68 let changelog = Changelog::new(ChangelogStorageConfig::default())
70 .await
71 .expect("Failed to initialize Changelog");
72
73 let loopback = ClaudeCodeLoopback::new(LoopbackStorageConfig::default())
75 .await
76 .expect("Failed to initialize ClaudeCodeLoopback");
77
78 let registry = Registry::with_defaults()
83 .await
84 .expect("Failed to initialize Registry");
85
86 let hub = Arc::new_cyclic(|weak_hub: &Weak<DynamicHub>| {
90 arbor.inject_parent(weak_hub.clone());
92 cone.inject_parent(weak_hub.clone());
93 claudecode.inject_parent(weak_hub.clone());
94
95 DynamicHub::new("substrate")
97 .register(Health::new())
98 .register(Echo::new())
99 .register(Bash::new())
100 .register(arbor)
101 .register(cone)
102 .register(claudecode)
103 .register(mustache)
104 .register(changelog.clone())
105 .register(loopback)
106 .register(registry)
108 .register(Interactive::new()) .register_hub(Solar::new())
110 });
111
112 let plexus_hash = hub.compute_hash();
114 match changelog.startup_check(&plexus_hash).await {
115 Ok((hash_changed, is_documented, message)) => {
116 if hash_changed && !is_documented {
117 tracing::error!("{}", message);
118 } else if hash_changed {
119 tracing::info!("{}", message);
120 } else {
121 tracing::debug!("{}", message);
122 }
123 }
124 Err(e) => {
125 tracing::error!("Changelog startup check failed: {}", e);
126 }
127 }
128
129 hub
130}