Initial workspace scaffold

Cargo workspace with 5 crates: buh-entity (pure data structs),
buh-data (Turso/libsql data access), buh-util (scraper, rules,
processor, sync modules), buh-cli (binary "buh" with client/daemon
subcommands), and buh-ws (axum WebSocket server).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-20 09:46:15 +02:00
commit b11a0b7c56
26 changed files with 4131 additions and 0 deletions

20
crates/buh-cli/Cargo.toml Normal file
View File

@@ -0,0 +1,20 @@
[package]
name = "buh-cli"
edition.workspace = true
version.workspace = true
[[bin]]
name = "buh"
path = "src/main.rs"
[dependencies]
buh-entity = { workspace = true }
buh-data = { workspace = true }
buh-util = { workspace = true }
clap = { workspace = true }
tokio = { workspace = true }
toml = { workspace = true }
serde = { workspace = true }
anyhow = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }

View File

@@ -0,0 +1,4 @@
pub async fn run() -> anyhow::Result<()> {
tracing::info!("client mode not yet implemented");
Ok(())
}

View File

@@ -0,0 +1,24 @@
use std::path::Path;
use buh_entity::config::DaemonConfig;
pub async fn run(config_path: &Path) -> anyhow::Result<()> {
let raw = std::fs::read_to_string(config_path)?;
let config: DaemonConfig = toml::from_str(&raw)?;
let db = buh_data::Db::connect(&config.database.url, config.database.auth_token.as_deref())
.await?;
db.migrate().await?;
if config.routines.scrape {
tracing::info!("scrape routine: not yet implemented");
}
if config.routines.process {
tracing::info!("process routine: not yet implemented");
}
if config.routines.sync {
tracing::info!("sync routine: not yet implemented");
}
Ok(())
}

View File

@@ -0,0 +1,37 @@
mod client;
mod daemon;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "buh", version, about = "Media automation engine")]
struct Cli {
#[command(subcommand)]
command: Option<Command>,
}
#[derive(Subcommand)]
enum Command {
/// Interactive client (default when no subcommand is given)
Client,
/// Run daemon routines from a configuration file
Daemon {
/// Path to daemon TOML configuration file
#[arg(long, default_value = "/etc/buh/daemon.toml")]
config: std::path::PathBuf,
},
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();
let cli = Cli::parse();
match cli.command.unwrap_or(Command::Client) {
Command::Client => client::run().await,
Command::Daemon { config } => daemon::run(&config).await,
}
}