//! `cube` — the CUBELinux-2 system CLI (local, in-process). //! //! One process holds ONE in-memory `CubeStore` shared by cubefs, cubecode and //! cubecrypt. Commands are issued as a script (file) or interactively (REPL); //! every command operates on that shared store, so `write` then `run` then //! `seal` then `open` all see the same cube. //! //! For a persistent store served over a socket by a long-running daemon, use //! `cube-server` + `cubec` instead (see `docs/integration.md`). //! //! Usage: //! cube # print this help //! cube demo # run the built-in integration demo //! cube repl # read commands from stdin, one per line //! cube script # read commands from , one per line //! //! Commands (operate on the shared cube): //! prog # write CUBEVM bytecode from op names //! write # store cubevm bytecode (hex/dec) at a path //! run # load the code cell at and run the VM //! ls # list a cubefs directory //! stat # getattr via cubefs //! seal # encrypt the record at (tf: none|gcm|chacha|xts) //! open # decrypt + decode + run the sealed record //! //! Coordinates are written `C.Z.Y.X` (decimal). Key cells live in Null space, //! so they are given directly as coordinates, not as cubefs paths. use std::io::BufRead; use cubesys::commands::Session; /// Command words understood by the shared interpreter. When `cube`'s first /// argument is one of these, it is run as a single command against a fresh /// in-memory store (the same path as `cube repl`), so the OS / a script can /// invoke e.g. `cube open /c001/z001/y001/x001 001.001.001.001 none` directly /// — this is the Phase-3 "open by CZYX + flags" surface made a first-class /// CLI command rather than REPL-only. fn is_command_word(w: &str) -> bool { matches!( w, "prog" | "write" | "run" | "ls" | "stat" | "seal" | "open" | "query" | "begin" | "commit" | "rollback" | "stats" | "audit" ) } fn main() { let args: Vec = std::env::args().collect(); match args.get(1).map(|s| s.as_str()) { None => print_help(), Some("demo") => cubesys::demo::run(), // A direct command word (e.g. `cube open `): run it // against a fresh in-memory session and exit with the result. This makes // the coordinate-addressed API a real CLI surface the OS can call. Some(word) if is_command_word(word) => { let line = args[1..].join(" "); let mut session = Session::new(); match session.exec(&line) { Ok(out) => println!("{out}"), Err(e) => { eprintln!("error: {e}"); std::process::exit(1); } } } Some("repl") => { let mut session = Session::new(); let stdin = std::io::stdin(); let lock = stdin.lock(); for line in lock.lines() { let line = match line { Ok(l) => l, Err(_) => break, }; if line.trim().is_empty() || line.starts_with('#') { continue; } match session.exec(&line) { Ok(out) => println!("{out}"), Err(e) => eprintln!("error: {e}"), } } } Some("script") => { let file = args.get(2).expect("script needs "); let text = std::fs::read_to_string(file).expect("cannot read script file"); let mut session = Session::new(); for line in text.lines() { if line.trim().is_empty() || line.starts_with('#') { continue; } match session.exec(line) { Ok(out) => println!("{out}"), Err(e) => { eprintln!("error: {e}"); std::process::exit(1); } } } } Some(other) => { eprintln!("unknown subcommand: {other}\n"); print_help(); std::process::exit(2); } } } fn print_help() { println!( "cube - CUBELinux-2 system CLI (cubefs + cubecode + cubecrypt over one store)\n\ \n\ Usage:\n \ cube show this help\n \ cube demo run the built-in integration demo\n \ cube repl read commands from stdin (one per line)\n \ cube script run commands from a file\n\ \nCommands:\n \ prog write CUBEVM bytecode from op names\n \ write store cubevm bytecode at a path\n \ run run the code cell at \n \ ls list a cubefs directory\n \ stat getattr via cubefs\n \ seal encrypt a record (tf: none|gcm|chacha|xts)\n \ open decrypt + decode + run a sealed record\n" ); }