1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! Mecha10 CLI Library
//!
//! This crate provides both a command-line interface and a library API for managing
//! Mecha10 robot projects. The library can be used programmatically by other tools.
//!
//! # Architecture
//!
//! The CLI follows a 3-layer architecture for maintainability and testability:
//!
//! ```text
//! Commands (clap Args) → Pure data structures, no logic
//! ↓
//! Handlers (orchestration) → Coordinate services, handle UI
//! ↓
//! Services (business logic)→ Reusable, testable logic
//! ↓
//! Mecha10 Core (framework) → Message passing runtime
//! ```
//!
//! # Library Usage
//!
//! ## Basic Project Operations
//!
//! ```rust,no_run
//! use mecha10_cli::{CliContext, services::ProjectService};
//! use std::path::Path;
//!
//! # async fn example() -> anyhow::Result<()> {
//! // Detect a Mecha10 project
//! let project = ProjectService::detect(Path::new("."))?;
//! println!("Project: {} v{}", project.name()?, project.version()?);
//!
//! // List project components
//! let nodes = project.list_nodes()?;
//! let drivers = project.list_drivers()?;
//! println!("Nodes: {:?}", nodes);
//! println!("Drivers: {:?}", drivers);
//!
//! // Validate project structure
//! project.validate()?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Working with Docker
//!
//! ```rust,no_run
//! use mecha10_cli::services::DockerService;
//!
//! # async fn example() -> anyhow::Result<()> {
//! let docker = DockerService::new();
//!
//! // Check Docker availability
//! docker.check_installation()?;
//! docker.check_daemon()?;
//!
//! // Manage services
//! docker.compose_up(true).await?;
//! let containers = docker.list_containers().await?;
//!
//! for container in containers {
//! println!("{}: {}", container.name, container.status);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Using CliContext
//!
//! ```rust,no_run
//! use mecha10_cli::CliContextBuilder;
//! use tracing::Level;
//!
//! # async fn example() -> anyhow::Result<()> {
//! // Build a context with custom settings
//! let mut ctx = CliContextBuilder::new()
//! .redis_url("redis://localhost:6380".to_string())
//! .log_level(Level::DEBUG)
//! .verbose(true)
//! .build()?;
//!
//! // Access services through context
//! let docker = ctx.docker();
//! let redis = ctx.redis()?;
//!
//! // Services are lazy-initialized
//! let project = ctx.project()?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Configuration Management
//!
//! ```rust,no_run
//! use mecha10_cli::services::{ConfigService, ProjectService};
//! use std::path::Path;
//!
//! # async fn example() -> anyhow::Result<()> {
//! // Detect the project root (walks up from the given path looking for
//! // mecha10.json), then load its config from that resolved path.
//! let project = ProjectService::detect(Path::new("."))?;
//! let config = ConfigService::load_from(&project.config_path()).await?;
//! println!("Robot ID: {}", config.robot.id);
//!
//! // Check if initialized
//! if ConfigService::is_initialized_here() {
//! println!("Project is initialized");
//! }
//! # Ok(())
//! # }
//! ```
pub use ;
pub use Level;
pub use ;