mecha10-cli 0.1.47

Mecha10 CLI tool
Documentation
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
//! Centralized path definitions for the CLI
//!
//! All hardcoded paths should be defined here to ensure consistency
//! and make it easy to update paths across the codebase.
//!
//! # Organization
//!
//! - **Project paths**: Paths relative to project root (mecha10.json location)
//! - **User paths**: Paths in user's home directory (~/.mecha10)
//! - **Docker paths**: Paths used inside Docker containers
//! - **Framework paths**: Paths within the mecha10 framework source

// Allow dead code during migration - paths will be used incrementally
#![allow(dead_code)]

use std::path::{Path, PathBuf};

// =============================================================================
// Project Structure - Paths relative to project root
// =============================================================================

/// Project configuration file
pub const PROJECT_CONFIG: &str = "mecha10.json";

/// Project directories
pub mod project {
    /// Node source code directory
    pub const NODES_DIR: &str = "nodes";

    /// Driver source code directory
    pub const DRIVERS_DIR: &str = "drivers";

    /// Types directory
    pub const TYPES_DIR: &str = "types";

    /// Behavior trees directory
    pub const BEHAVIORS_DIR: &str = "behaviors";

    /// Assets directory
    pub const ASSETS_DIR: &str = "assets";

    /// Assets images subdirectory
    pub const ASSETS_IMAGES_DIR: &str = "assets/images";

    /// Models directory (ONNX models, etc.)
    pub const MODELS_DIR: &str = "models";

    /// Logs directory
    pub const LOGS_DIR: &str = "logs";

    /// Simulation directory
    pub const SIMULATION_DIR: &str = "simulation";

    /// Simulation models directory
    pub const SIMULATION_MODELS_DIR: &str = "simulation/models";

    /// Simulation environments directory
    pub const SIMULATION_ENVIRONMENTS_DIR: &str = "simulation/environments";

    /// Get path to a model's config file
    pub fn model_config(model_name: &str) -> String {
        format!("simulation/models/{}/model.json", model_name)
    }

    /// Get path to an environment's config file
    pub fn environment_config(env_name: &str) -> String {
        format!("simulation/environments/{}/environment.json", env_name)
    }

    /// Simulation Godot project directory
    pub const SIMULATION_GODOT_DIR: &str = "simulation/godot";

    /// Cargo build target directory
    pub const TARGET_DIR: &str = "target";

    /// Source directory
    pub const SRC_DIR: &str = "src";
}

/// Configuration paths within project
pub mod config {
    /// Base configs directory
    pub const DIR: &str = "configs";

    /// Node configs base directory
    pub const NODES_DIR: &str = "configs/nodes";

    /// Framework node configs (@mecha10 scope)
    pub const NODES_MECHA10_DIR: &str = "configs/nodes/@mecha10";

    /// Local node configs (@local scope)
    pub const NODES_LOCAL_DIR: &str = "configs/nodes/@local";

    /// Simulation configs directory
    pub const SIMULATION_DIR: &str = "configs/simulation";

    /// Simulation config file
    pub const SIMULATION_CONFIG: &str = "configs/simulation/config.json";

    /// Get config path for a framework node
    pub fn framework_node(node_name: &str) -> String {
        format!("configs/nodes/@mecha10/{}/config.json", node_name)
    }

    /// Get config path for a local node
    pub fn local_node(node_name: &str) -> String {
        format!("configs/nodes/@local/{}/config.json", node_name)
    }

    /// Get config path for a project node (plain name)
    pub fn project_node(node_name: &str) -> String {
        format!("configs/nodes/{}/config.json", node_name)
    }
}

/// Docker-related paths within project
pub mod docker {
    /// Docker directory
    pub const DIR: &str = "docker";

    /// Main docker-compose file
    pub const COMPOSE_FILE: &str = "docker/docker-compose.yml";

    /// Remote nodes docker-compose file
    pub const COMPOSE_REMOTE_FILE: &str = "docker/docker-compose.remote.yml";

    /// Remote nodes Dockerfile
    pub const DOCKERFILE_REMOTE: &str = "docker/Dockerfile.remote";

    /// Robot builder Dockerfile (for cross-compilation)
    pub const DOCKERFILE_ROBOT_BUILDER: &str = "docker/robot-builder.Dockerfile";
}

/// Environment files
pub mod env {
    /// Environment example file
    pub const EXAMPLE: &str = ".env.example";

    /// Environment file
    pub const FILE: &str = ".env";
}

/// Meta files (README, gitignore, etc.)
pub mod meta {
    /// README file
    pub const README: &str = "README.md";

    /// Git ignore file
    pub const GITIGNORE: &str = ".gitignore";

    /// Package.json for Node.js tooling
    pub const PACKAGE_JSON: &str = "package.json";

    /// Python requirements
    pub const REQUIREMENTS_TXT: &str = "requirements.txt";

    /// Lint config
    pub const LS_LINT_CONFIG: &str = ".ls-lint.yml";
}

/// Rust project files
pub mod rust {
    /// Cargo workspace manifest
    pub const CARGO_TOML: &str = "Cargo.toml";

    /// Cargo lock file
    pub const CARGO_LOCK: &str = "Cargo.lock";

    /// Main entry point
    pub const MAIN_RS: &str = "src/main.rs";

    /// Library entry point
    pub const LIB_RS: &str = "src/lib.rs";

    /// Build script
    pub const BUILD_RS: &str = "build.rs";

    /// Rustfmt config
    pub const RUSTFMT_TOML: &str = "rustfmt.toml";

    /// Cargo config directory
    pub const CARGO_CONFIG_DIR: &str = ".cargo";

    /// Cargo config file
    pub const CARGO_CONFIG: &str = ".cargo/config.toml";
}

/// Model files within a model directory
pub mod model {
    /// ONNX model file
    pub const ONNX_FILE: &str = "model.onnx";

    /// Labels file
    pub const LABELS_FILE: &str = "labels.txt";

    /// Model config file
    pub const CONFIG_FILE: &str = "config.json";
}

// =============================================================================
// User Home Paths - Paths in ~/.mecha10
// =============================================================================

/// User-level paths in home directory
pub mod user {
    use std::path::PathBuf;

    /// Base mecha10 directory in user home
    pub const MECHA10_DIR: &str = ".mecha10";

    /// Credentials file
    pub const CREDENTIALS_FILE: &str = ".mecha10/credentials.json";

    /// Templates cache directory
    pub const TEMPLATES_DIR: &str = ".mecha10/templates";

    /// Simulation assets cache directory
    pub const SIMULATION_DIR: &str = ".mecha10/simulation";

    /// Current simulation assets symlink
    pub const SIMULATION_CURRENT: &str = ".mecha10/simulation/current";

    /// Simulation version file
    pub const SIMULATION_VERSION: &str = ".mecha10/simulation/version";

    /// Binary installation directory
    pub const BIN_DIR: &str = ".mecha10/bin";

    /// Get the base mecha10 directory path
    pub fn mecha10_dir() -> PathBuf {
        dirs::home_dir().unwrap_or_else(|| PathBuf::from(".")).join(MECHA10_DIR)
    }

    /// Get the credentials file path
    pub fn credentials_file() -> PathBuf {
        dirs::home_dir()
            .unwrap_or_else(|| PathBuf::from("."))
            .join(CREDENTIALS_FILE)
    }

    /// Get the templates cache directory
    pub fn templates_dir() -> PathBuf {
        mecha10_dir().join("templates")
    }

    /// Get the simulation assets directory
    pub fn simulation_dir() -> PathBuf {
        mecha10_dir().join("simulation")
    }

    /// Get the current simulation assets path
    pub fn simulation_current() -> PathBuf {
        mecha10_dir().join("simulation/current")
    }

    /// Get the binary directory
    pub fn bin_dir() -> PathBuf {
        mecha10_dir().join("bin")
    }

    /// Get path to a binary in the mecha10 bin directory
    pub fn bin(name: &str) -> PathBuf {
        bin_dir().join(name)
    }

    /// Get path to a binary in cargo bin directory
    pub fn cargo_bin(name: &str) -> PathBuf {
        dirs::home_dir()
            .unwrap_or_else(|| PathBuf::from("."))
            .join(".cargo/bin")
            .join(name)
    }

    /// Get path to a binary in local bin directory
    pub fn local_bin(name: &str) -> PathBuf {
        dirs::home_dir()
            .unwrap_or_else(|| PathBuf::from("."))
            .join(".local/bin")
            .join(name)
    }
}

// =============================================================================
// Docker Container Paths - Paths used inside containers
// =============================================================================

/// Paths used inside Docker containers
pub mod container {
    /// Project mount point in container
    pub const PROJECT_ROOT: &str = "/project";

    /// Framework mount point in container
    pub const FRAMEWORK_ROOT: &str = "/mecha10";

    /// App directory (for mecha10-remote)
    pub const APP_ROOT: &str = "/app";

    /// Config file in mecha10-remote container
    pub const REMOTE_CONFIG: &str = "/app/mecha10.json";

    /// Framework Godot project path (new structure)
    pub const FRAMEWORK_GODOT_PROJECT: &str = "/mecha10/packages/simulation/godot-project";

    /// Framework Godot project path (legacy)
    pub const FRAMEWORK_GODOT_PROJECT_LEGACY: &str = "/mecha10/godot-project";

    /// Get project-relative path inside container
    pub fn project_path(relative: &str) -> String {
        format!("{}/{}", PROJECT_ROOT, relative)
    }

    /// Get framework-relative path inside container
    pub fn framework_path(relative: &str) -> String {
        format!("{}/{}", FRAMEWORK_ROOT, relative)
    }
}

// =============================================================================
// Framework Paths - Paths within mecha10 framework source
// =============================================================================

/// Paths within the mecha10 framework source
pub mod framework {
    /// Packages directory
    pub const PACKAGES_DIR: &str = "packages";

    /// Nodes package directory
    pub const NODES_DIR: &str = "packages/nodes";

    /// Drivers package directory
    pub const DRIVERS_DIR: &str = "packages/drivers";

    /// Services package directory
    pub const SERVICES_DIR: &str = "packages/services";

    /// Simulation package directory
    pub const SIMULATION_DIR: &str = "packages/simulation";

    /// Simulation Godot project
    pub const SIMULATION_GODOT_DIR: &str = "packages/simulation/godot-project";

    /// Simulation models directory
    pub const SIMULATION_MODELS_DIR: &str = "packages/simulation/models";

    /// Simulation environments directory
    pub const SIMULATION_ENVIRONMENTS_DIR: &str = "packages/simulation/environments";

    /// Robot tasks environments directory (for environment matching)
    pub const ROBOT_TASKS_DIR: &str = "packages/simulation/environments/robot-tasks";

    /// Robot tasks catalog file
    pub const ROBOT_TASKS_CATALOG: &str = "packages/simulation/environments/robot-tasks/catalog.json";

    /// Python taskrunner package
    pub const TASKRUNNER_DIR: &str = "packages/taskrunner";

    /// Release binary
    pub const RELEASE_BINARY: &str = "target/release/mecha10";

    /// Debug binary
    pub const DEBUG_BINARY: &str = "target/debug/mecha10";

    /// Node runner release binary
    pub const NODE_RUNNER_RELEASE: &str = "target/release/mecha10-node-runner";

    /// Node runner debug binary
    pub const NODE_RUNNER_DEBUG: &str = "target/debug/mecha10-node-runner";

    /// Get node package path
    pub fn node_package(node_name: &str) -> String {
        format!("packages/nodes/{}", node_name)
    }

    /// Get node config path within framework
    pub fn node_config(node_name: &str) -> String {
        format!("packages/nodes/{}/configs/config.json", node_name)
    }

    /// Get node lib.rs path within framework
    pub fn node_lib_rs(node_name: &str) -> String {
        format!("packages/nodes/{}/src/lib.rs", node_name)
    }
}

// =============================================================================
// External URLs
// =============================================================================

/// External service URLs
pub mod urls {
    /// GitHub repository for user-tools (templates, assets)
    pub const USER_TOOLS_REPO: &str = "mecha-industries/user-tools";

    /// Remote image manifest URL
    pub const REMOTE_MANIFEST: &str =
        "https://raw.githubusercontent.com/mecha-industries/user-tools/main/mecha10-remote/manifest.json";

    /// Default authentication URL
    pub const AUTH_URL: &str = "https://mecha.industries/api/auth";
}

// =============================================================================
// Helper Functions
// =============================================================================

/// Build a target output path
pub fn target_path(profile: &str, binary: &str) -> String {
    format!("target/{}/{}", profile, binary)
}

/// Build a target output path with optional target triple
pub fn target_path_with_triple(target: Option<&str>, profile: &str) -> String {
    match target {
        Some(t) => format!("target/{}/{}", t, profile),
        None => format!("target/{}", profile),
    }
}

/// Get the project root by finding mecha10.json
pub fn find_project_root(start: &Path) -> Option<PathBuf> {
    let mut current = start.to_path_buf();
    loop {
        if current.join(PROJECT_CONFIG).exists() {
            return Some(current);
        }
        if !current.pop() {
            return None;
        }
    }
}

/// Check if a directory is a mecha10 project
pub fn is_project_dir(dir: &Path) -> bool {
    dir.join(PROJECT_CONFIG).exists()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_config_paths() {
        assert_eq!(
            config::framework_node("object-detector"),
            "configs/nodes/@mecha10/object-detector/config.json"
        );
        assert_eq!(
            config::local_node("my-node"),
            "configs/nodes/@local/my-node/config.json"
        );
        assert_eq!(config::project_node("camera"), "configs/nodes/camera/config.json");
    }

    #[test]
    fn test_target_path() {
        assert_eq!(target_path("release", "my-node"), "target/release/my-node");
        assert_eq!(
            target_path_with_triple(Some("aarch64-unknown-linux-gnu"), "release"),
            "target/aarch64-unknown-linux-gnu/release"
        );
        assert_eq!(target_path_with_triple(None, "debug"), "target/debug");
    }

    #[test]
    fn test_container_paths() {
        assert_eq!(
            container::project_path("configs/test.json"),
            "/project/configs/test.json"
        );
        assert_eq!(container::framework_path("packages/core"), "/mecha10/packages/core");
    }
}