sergio/takana
> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…
⎇ 8bf1623044075274682e4351a0f8e120047c2bed
crates/hammer-cli/src/main.rs
Historia
Quién tocó qué
crudo
Scaffold inicial: workspace Rust + SDDs completos
1//! `hammer` — el punto de entrada de todo flujo manual. Ver `docs/`.
2//!
3//! Los subcomandos están mapeados a las fases del roadmap (`docs/10-roadmap.md`). Los que aún
4//! no están implementados devuelven un error claro indicando su fase, para que el esqueleto
5//! sea navegable desde el día uno.
6
7use clap::{Parser, Subcommand};
8
9const DEFAULT_STORE: &str = "/store";
10
11#[derive(Parser)]
12#[command(
13 name = "hammer",
14 version,
15 about = "Laboratorio funcional en el sótano, terminal mutable arriba.",
16 long_about = "hammer: distro AI-nativa. Ver docs/ para el diseño completo."
17)]
18struct Cli {
19 /// Ruta del content-addressed store.
20 #[arg(long, default_value = DEFAULT_STORE, global = true)]
21 store: String,
22
23 #[command(subcommand)]
24 cmd: Cmd,
25}
26
27#[derive(Subcommand)]
28enum Cmd {
29 /// [Fase 0] Compila una receta y la sella en el store.
30 Build {
31 /// Ruta a la receta TOML.
32 recipe: String,
33 },
34 /// [Fase 1] Proyecta un artefacto del store al FHS (real o de overlay).
35 Hydrate {
36 hash: String,
37 #[arg(long, default_value = "/")]
38 into: String,
39 },
40 /// [Fase 2] Monta un overlay de experimentación sobre los directorios del sistema.
41 Try,
42 /// [Fase 2] Fusiona el overlay activo al FHS real (registra en el diario).
43 Commit,
44 /// [Fase 2] Descarta el overlay activo; vuelve al estado base.
45 Discard,
46 /// [Fase 2] Muestra el estado de overlays activos.
47 Status,
48 /// [Fase 3] Ver/seguir el diario de mutaciones.
49 Journal,
50 /// [Fase 4] Aplica un manifiesto .swm (reproduce y lo deja en un overlay).
51 Apply { file: String },
52 /// [Fase 4] Exporta el delta del sistema como manifiesto .swm.
53 Export {
54 #[arg(long)]
55 base: Option<String>,
56 },
57 /// [Fase 5] Envía un comando al init (proxy a /run/init.control).
58 Ctl { line: String },
59}
60
61fn main() -> anyhow::Result<()> {
62 tracing_subscriber::fmt()
63 .with_env_filter(
64 tracing_subscriber::EnvFilter::try_from_default_env()
65 .unwrap_or_else(|_| "info".into()),
66 )
67 .init();
68
69 let cli = Cli::parse();
70 let store = hammer_core::Store::open(&cli.store)?;
71
72 match cli.cmd {
73 Cmd::Build { recipe } => {
74 let text = std::fs::read_to_string(&recipe)?;
75 let recipe = hammer_core::Recipe::from_toml(&text)?;
76 let hash = hammer_build::build(&recipe, &store)?;
77 println!("{hash}");
78 }
79 Cmd::Hydrate { hash, into } => {
80 println!("[fase 1 pendiente] hydrate {hash} into {into}");
81 }
82 Cmd::Try | Cmd::Commit | Cmd::Discard | Cmd::Status => {
83 println!("[fase 2 pendiente] overlay — ver docs/04-overlay.md");
84 }
85 Cmd::Journal => {
86 println!("[fase 3 pendiente] diario — ver docs/05-journal.md");
87 }
88 Cmd::Apply { file } => {
89 println!("[fase 4 pendiente] apply {file} — ver docs/06-swm-format.md");
90 }
91 Cmd::Export { base } => {
92 println!("[fase 4 pendiente] export base={base:?} — ver docs/05-journal.md");
93 }
94 Cmd::Ctl { line } => {
95 println!("[fase 5 pendiente] ctl {line:?} — ver docs/07-agent-bus.md");
96 }
97 }
98 Ok(())
99}