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
130
131
132
133
134
135
//! 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 ;