merge: rename tahuantinsuyu → cosmobiologia

This commit is contained in:
sergio
2026-05-19 00:46:07 +00:00
34 changed files with 325 additions and 315 deletions
Generated
+150 -140
View File
@@ -2130,6 +2130,156 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "cosmobiologia"
version = "0.1.0"
dependencies = [
"brahman-sidecar",
"cosmobiologia-canvas",
"cosmobiologia-card",
"cosmobiologia-engine",
"cosmobiologia-model",
"cosmobiologia-modules",
"cosmobiologia-panel",
"cosmobiologia-store",
"cosmobiologia-theme",
"cosmobiologia-tree",
"directories",
"gpui",
"serde_json",
"yahweh-core",
"yahweh-theme",
"yahweh-widget-container-core",
"yahweh-widget-splitter",
"yahweh-widget-theme-switcher",
]
[[package]]
name = "cosmobiologia-canvas"
version = "0.1.0"
dependencies = [
"cosmobiologia-engine",
"cosmobiologia-model",
"cosmobiologia-modules",
"cosmobiologia-render",
"cosmobiologia-theme",
"gpui",
"yahweh-theme",
]
[[package]]
name = "cosmobiologia-card"
version = "0.1.0"
dependencies = [
"brahman-card",
"brahman-sidecar",
"cosmobiologia-engine",
"cosmobiologia-model",
"directories",
"postcard",
"serde",
"thiserror 2.0.18",
"tokio",
"tracing",
"ulid",
]
[[package]]
name = "cosmobiologia-cli"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"cosmobiologia-card",
"cosmobiologia-model",
"serde_json",
"tokio",
]
[[package]]
name = "cosmobiologia-engine"
version = "0.1.0"
dependencies = [
"cosmobiologia-model",
"cosmobiologia-render",
"eternal-astrology",
"eternal-sky",
"serde",
"thiserror 2.0.18",
]
[[package]]
name = "cosmobiologia-model"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
"thiserror 2.0.18",
"ulid",
]
[[package]]
name = "cosmobiologia-modules"
version = "0.1.0"
dependencies = [
"cosmobiologia-engine",
"cosmobiologia-model",
"serde",
"serde_json",
]
[[package]]
name = "cosmobiologia-panel"
version = "0.1.0"
dependencies = [
"cosmobiologia-model",
"cosmobiologia-modules",
"cosmobiologia-theme",
"gpui",
"serde_json",
"yahweh-theme",
]
[[package]]
name = "cosmobiologia-render"
version = "0.1.0"
dependencies = [
"cosmobiologia-model",
"serde",
]
[[package]]
name = "cosmobiologia-store"
version = "0.1.0"
dependencies = [
"cosmobiologia-model",
"rusqlite",
"serde",
"serde_json",
"thiserror 2.0.18",
"ulid",
]
[[package]]
name = "cosmobiologia-theme"
version = "0.1.0"
dependencies = [
"gpui",
"yahweh-theme",
]
[[package]]
name = "cosmobiologia-tree"
version = "0.1.0"
dependencies = [
"cosmobiologia-model",
"cosmobiologia-store",
"gpui",
"yahweh-theme",
"yahweh-widget-text-input",
"yahweh-widget-tree",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.17" version = "0.2.17"
@@ -10900,146 +11050,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
[[package]]
name = "tahuantinsuyu"
version = "0.1.0"
dependencies = [
"brahman-sidecar",
"directories",
"gpui",
"serde_json",
"tahuantinsuyu-canvas",
"tahuantinsuyu-card",
"tahuantinsuyu-engine",
"tahuantinsuyu-model",
"tahuantinsuyu-modules",
"tahuantinsuyu-panel",
"tahuantinsuyu-store",
"tahuantinsuyu-theme",
"tahuantinsuyu-tree",
"yahweh-core",
"yahweh-theme",
"yahweh-widget-container-core",
"yahweh-widget-splitter",
"yahweh-widget-theme-switcher",
]
[[package]]
name = "tahuantinsuyu-canvas"
version = "0.1.0"
dependencies = [
"gpui",
"tahuantinsuyu-engine",
"tahuantinsuyu-model",
"tahuantinsuyu-modules",
"tahuantinsuyu-theme",
"yahweh-theme",
]
[[package]]
name = "tahuantinsuyu-card"
version = "0.1.0"
dependencies = [
"brahman-card",
"brahman-sidecar",
"directories",
"postcard",
"serde",
"tahuantinsuyu-engine",
"tahuantinsuyu-model",
"thiserror 2.0.18",
"tokio",
"tracing",
"ulid",
]
[[package]]
name = "tahuantinsuyu-cli"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"serde_json",
"tahuantinsuyu-card",
"tahuantinsuyu-model",
"tokio",
]
[[package]]
name = "tahuantinsuyu-engine"
version = "0.1.0"
dependencies = [
"eternal-astrology",
"eternal-sky",
"serde",
"tahuantinsuyu-model",
"thiserror 2.0.18",
]
[[package]]
name = "tahuantinsuyu-model"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
"thiserror 2.0.18",
"ulid",
]
[[package]]
name = "tahuantinsuyu-modules"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
"tahuantinsuyu-engine",
"tahuantinsuyu-model",
]
[[package]]
name = "tahuantinsuyu-panel"
version = "0.1.0"
dependencies = [
"gpui",
"serde_json",
"tahuantinsuyu-model",
"tahuantinsuyu-modules",
"tahuantinsuyu-theme",
"yahweh-theme",
]
[[package]]
name = "tahuantinsuyu-store"
version = "0.1.0"
dependencies = [
"rusqlite",
"serde",
"serde_json",
"tahuantinsuyu-model",
"thiserror 2.0.18",
"ulid",
]
[[package]]
name = "tahuantinsuyu-theme"
version = "0.1.0"
dependencies = [
"gpui",
"yahweh-theme",
]
[[package]]
name = "tahuantinsuyu-tree"
version = "0.1.0"
dependencies = [
"gpui",
"tahuantinsuyu-model",
"tahuantinsuyu-store",
"yahweh-theme",
"yahweh-widget-text-input",
"yahweh-widget-tree",
]
[[package]] [[package]]
name = "take-until" name = "take-until"
version = "0.2.0" version = "0.2.0"
+13 -13
View File
@@ -134,18 +134,18 @@ members = [
"crates/modules/barra/barra-web", "crates/modules/barra/barra-web",
# ============================================================ # ============================================================
# modules/tahuantinsuyu/ — estudio de astrología profesional # modules/cosmobiologia/ — estudio de astrología profesional
# ============================================================ # ============================================================
"crates/modules/tahuantinsuyu/tahuantinsuyu-card", "crates/modules/cosmobiologia/cosmobiologia-card",
"crates/modules/tahuantinsuyu/tahuantinsuyu-model", "crates/modules/cosmobiologia/cosmobiologia-model",
"crates/modules/tahuantinsuyu/tahuantinsuyu-store", "crates/modules/cosmobiologia/cosmobiologia-store",
"crates/modules/tahuantinsuyu/tahuantinsuyu-render", "crates/modules/cosmobiologia/cosmobiologia-render",
"crates/modules/tahuantinsuyu/tahuantinsuyu-engine", "crates/modules/cosmobiologia/cosmobiologia-engine",
"crates/modules/tahuantinsuyu/tahuantinsuyu-modules", "crates/modules/cosmobiologia/cosmobiologia-modules",
"crates/modules/tahuantinsuyu/tahuantinsuyu-theme", "crates/modules/cosmobiologia/cosmobiologia-theme",
"crates/modules/tahuantinsuyu/tahuantinsuyu-canvas", "crates/modules/cosmobiologia/cosmobiologia-canvas",
"crates/modules/tahuantinsuyu/tahuantinsuyu-tree", "crates/modules/cosmobiologia/cosmobiologia-tree",
"crates/modules/tahuantinsuyu/tahuantinsuyu-panel", "crates/modules/cosmobiologia/cosmobiologia-panel",
# ============================================================ # ============================================================
# apps/ — apps que consumen el protocolo (yahweh modules+shell) # apps/ — apps que consumen el protocolo (yahweh modules+shell)
@@ -170,8 +170,8 @@ members = [
"crates/apps/lapaloma-stream-demo", "crates/apps/lapaloma-stream-demo",
"crates/apps/lapaloma-phosphor-demo", "crates/apps/lapaloma-phosphor-demo",
"crates/apps/lapaloma-financial-demo", "crates/apps/lapaloma-financial-demo",
"crates/apps/tahuantinsuyu", "crates/apps/cosmobiologia",
"crates/apps/tahuantinsuyu-cli", "crates/apps/cosmobiologia-cli",
] ]
[workspace.package] [workspace.package]
@@ -1,18 +1,18 @@
[package] [package]
name = "tahuantinsuyu-cli" name = "cosmobiologia-cli"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
description = "Tahuantinsuyu — CLI cliente del service socket. Pide cómputos de cartas sin abrir la GUI." description = "Tahuantinsuyu — CLI cliente del service socket. Pide cómputos de cartas sin abrir la GUI."
[dependencies] [dependencies]
tahuantinsuyu-card = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-card" } cosmobiologia-card = { path = "../../modules/cosmobiologia/cosmobiologia-card" }
tahuantinsuyu-model = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-model" } cosmobiologia-model = { path = "../../modules/cosmobiologia/cosmobiologia-model" }
clap = { workspace = true } clap = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
[[bin]] [[bin]]
name = "tahuantinsuyu-cli" name = "cosmobiologia-cli"
path = "src/main.rs" path = "src/main.rs"
@@ -1,9 +1,9 @@
//! `tahuantinsuyu-cli` — cliente del service socket de Tahuantinsuyu. //! `cosmobiologia-cli` — cliente del service socket de Tahuantinsuyu.
//! //!
//! Pide cómputos de cartas sin abrir la GUI. Útil para integraciones, //! Pide cómputos de cartas sin abrir la GUI. Útil para integraciones,
//! scripts y para verificar end-to-end que el data plane brahman está //! scripts y para verificar end-to-end que el data plane brahman está
//! sirviendo. Conecta al socket que la app GUI expone (default //! sirviendo. Conecta al socket que la app GUI expone (default
//! `$XDG_CACHE_HOME/tahuantinsuyu/service.sock`). //! `$XDG_CACHE_HOME/cosmobiologia/service.sock`).
//! //!
//! ## Comandos //! ## Comandos
//! //!
@@ -15,7 +15,7 @@
//! ## Ejemplo //! ## Ejemplo
//! //!
//! ```bash //! ```bash
//! cargo run -p tahuantinsuyu-cli -- natal \ //! cargo run -p cosmobiologia-cli -- natal \
//! --year 1987 --month 3 --day 14 \ //! --year 1987 --month 3 --day 14 \
//! --hour 5 --minute 22 --tz-min -240 \ //! --hour 5 --minute 22 --tz-min -240 \
//! --lat 10.4806 --lon -66.9036 \ //! --lat 10.4806 --lon -66.9036 \
@@ -26,12 +26,12 @@ use std::path::PathBuf;
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use tahuantinsuyu_card::service::{self, ComputeRequest, ComputeResponse}; use cosmobiologia_card::service::{self, ComputeRequest, ComputeResponse};
use tahuantinsuyu_model::{StoredBirthData, StoredChartConfig}; use cosmobiologia_model::{StoredBirthData, StoredChartConfig};
#[derive(Parser)] #[derive(Parser)]
#[command( #[command(
name = "tahuantinsuyu-cli", name = "cosmobiologia-cli",
version, version,
about = "Cliente del service socket de Tahuantinsuyu." about = "Cliente del service socket de Tahuantinsuyu."
)] )]
@@ -1,20 +1,20 @@
[package] [package]
name = "tahuantinsuyu" name = "cosmobiologia"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
description = "Tahuantinsuyu — estudio profesional de astrología. Tree + canvas + panel sobre yahweh + eternal-astrology." description = "Tahuantinsuyu — estudio profesional de astrología. Tree + canvas + panel sobre yahweh + eternal-astrology."
[dependencies] [dependencies]
tahuantinsuyu-card = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-card" } cosmobiologia-card = { path = "../../modules/cosmobiologia/cosmobiologia-card" }
tahuantinsuyu-canvas = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-canvas" } cosmobiologia-canvas = { path = "../../modules/cosmobiologia/cosmobiologia-canvas" }
tahuantinsuyu-engine = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-engine" } cosmobiologia-engine = { path = "../../modules/cosmobiologia/cosmobiologia-engine" }
tahuantinsuyu-model = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-model" } cosmobiologia-model = { path = "../../modules/cosmobiologia/cosmobiologia-model" }
tahuantinsuyu-modules = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-modules" } cosmobiologia-modules = { path = "../../modules/cosmobiologia/cosmobiologia-modules" }
tahuantinsuyu-panel = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-panel" } cosmobiologia-panel = { path = "../../modules/cosmobiologia/cosmobiologia-panel" }
tahuantinsuyu-store = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-store" } cosmobiologia-store = { path = "../../modules/cosmobiologia/cosmobiologia-store" }
tahuantinsuyu-theme = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-theme" } cosmobiologia-theme = { path = "../../modules/cosmobiologia/cosmobiologia-theme" }
tahuantinsuyu-tree = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-tree" } cosmobiologia-tree = { path = "../../modules/cosmobiologia/cosmobiologia-tree" }
brahman-sidecar = { path = "../../shared/brahman-sidecar" } brahman-sidecar = { path = "../../shared/brahman-sidecar" }
yahweh-core = { workspace = true } yahweh-core = { workspace = true }
@@ -31,5 +31,5 @@ serde_json = { workspace = true }
gpui = { workspace = true, features = ["test-support"] } gpui = { workspace = true, features = ["test-support"] }
[[bin]] [[bin]]
name = "tahuantinsuyu" name = "cosmobiologia"
path = "src/main.rs" path = "src/main.rs"
@@ -1,10 +1,10 @@
//! Tahuantinsuyu — binario standalone. //! Tahuantinsuyu — binario standalone.
//! //!
//! Boot: //! Boot:
//! 1. `tahuantinsuyu_card::spawn_sidecar()` se presenta al Init brahman //! 1. `cosmobiologia_card::spawn_sidecar()` se presenta al Init brahman
//! (fire-and-forget; si no hay Init, la app sigue standalone). //! (fire-and-forget; si no hay Init, la app sigue standalone).
//! 2. Abre la DB SQLite en `$XDG_DATA_HOME/tahuantinsuyu/charts.db` //! 2. Abre la DB SQLite en `$XDG_DATA_HOME/cosmobiologia/charts.db`
//! (fallback a `~/.local/share/tahuantinsuyu/charts.db`). //! (fallback a `~/.local/share/cosmobiologia/charts.db`).
//! 3. Levanta GPUI con [`yahweh_theme::Theme::install_default`]. //! 3. Levanta GPUI con [`yahweh_theme::Theme::install_default`].
//! 4. Compone el shell: [`Shell`] dueño del tree (izq), canvas (centro) //! 4. Compone el shell: [`Shell`] dueño del tree (izq), canvas (centro)
//! y panel (abajo). Cablea las suscripciones cross-widget. //! y panel (abajo). Cablea las suscripciones cross-widget.
@@ -33,7 +33,7 @@ use gpui::{
WindowOptions, px, size, WindowOptions, px, size,
}; };
use tahuantinsuyu_store::Store; use cosmobiologia_store::Store;
use yahweh_theme::Theme; use yahweh_theme::Theme;
use crate::shell::Shell; use crate::shell::Shell;
@@ -43,14 +43,14 @@ const APP_TITLE: &str = "Tahuantinsuyu";
fn main() { fn main() {
// Sidecar brahman primero — si el Init está corriendo, nos presentamos. // Sidecar brahman primero — si el Init está corriendo, nos presentamos.
tahuantinsuyu_card::spawn_sidecar(); cosmobiologia_card::spawn_sidecar();
// Service socket: thread separado escuchando ComputeRequest. Otros // Service socket: thread separado escuchando ComputeRequest. Otros
// módulos brahman pueden conectar y pedir cómputos de cartas // módulos brahman pueden conectar y pedir cómputos de cartas
// natales sin GUI. Si el bind falla (socket ya tomado, sin // natales sin GUI. Si el bind falla (socket ya tomado, sin
// permisos), loggea warn y la app sigue corriendo standalone. // permisos), loggea warn y la app sigue corriendo standalone.
let service_socket = tahuantinsuyu_card::service::default_service_socket(); let service_socket = cosmobiologia_card::service::default_service_socket();
eprintln!("[tahuantinsuyu] service socket → {}", service_socket.display()); eprintln!("[cosmobiologia] service socket → {}", service_socket.display());
tahuantinsuyu_card::service::spawn_service_thread(service_socket); cosmobiologia_card::service::spawn_service_thread(service_socket);
// DB en directorio de datos del usuario. // DB en directorio de datos del usuario.
let db_path = resolve_db_path(); let db_path = resolve_db_path();
@@ -58,7 +58,7 @@ fn main() {
Ok(s) => s, Ok(s) => s,
Err(e) => { Err(e) => {
eprintln!( eprintln!(
"[tahuantinsuyu] no se pudo abrir la DB en {:?}: {} — usando memoria", "[cosmobiologia] no se pudo abrir la DB en {:?}: {} — usando memoria",
db_path, e db_path, e
); );
Store::in_memory().expect("in-memory store") Store::in_memory().expect("in-memory store")
@@ -86,7 +86,7 @@ fn main() {
} }
fn resolve_db_path() -> PathBuf { fn resolve_db_path() -> PathBuf {
if let Some(dirs) = directories::ProjectDirs::from("net", "gioser", "tahuantinsuyu") { if let Some(dirs) = directories::ProjectDirs::from("net", "gioser", "cosmobiologia") {
let dir = dirs.data_dir().to_path_buf(); let dir = dirs.data_dir().to_path_buf();
let _ = std::fs::create_dir_all(&dir); let _ = std::fs::create_dir_all(&dir);
return dir.join(DB_FILENAME); return dir.join(DB_FILENAME);
@@ -28,20 +28,20 @@ use gpui::{
Window, div, prelude::*, px, Window, div, prelude::*, px,
}; };
use tahuantinsuyu_canvas::{ use cosmobiologia_canvas::{
AstrologyCanvas, CanvasEvent, CanvasMode, ThumbnailItem, ThumbnailScope, AstrologyCanvas, CanvasEvent, CanvasMode, ThumbnailItem, ThumbnailScope,
}; };
use tahuantinsuyu_engine::{ use cosmobiologia_engine::{
LayerKind, NatalOptions, OUTER_RING_MODULES, PipelineRequest, compose_with_options, LayerKind, NatalOptions, OUTER_RING_MODULES, PipelineRequest, compose_with_options,
svg_export, svg_export,
}; };
use tahuantinsuyu_model::{ use cosmobiologia_model::{
Chart, ChartId, ChartKind, ContactId, FreeChartId, ModuleState, StoredBirthData, Chart, ChartId, ChartKind, ContactId, FreeChartId, ModuleState, StoredBirthData,
StoredChartConfig, TreeSelection, StoredChartConfig, TreeSelection,
}; };
use tahuantinsuyu_panel::{ChartOption, ControlPanel, PanelEvent}; use cosmobiologia_panel::{ChartOption, ControlPanel, PanelEvent};
use tahuantinsuyu_store::Store; use cosmobiologia_store::Store;
use tahuantinsuyu_tree::{ use cosmobiologia_tree::{
parse_city_atlas_tsv, FreeChartEntry, TahuantinsuyuTree, TreeEvent, parse_city_atlas_tsv, FreeChartEntry, TahuantinsuyuTree, TreeEvent,
}; };
use yahweh_core::{LayoutDirection, NodeId}; use yahweh_core::{LayoutDirection, NodeId};
@@ -147,7 +147,7 @@ impl Shell {
let tree = cx.new(|cx| { let tree = cx.new(|cx| {
let mut t = TahuantinsuyuTree::new(store.clone(), cx); let mut t = TahuantinsuyuTree::new(store.clone(), cx);
// Si hay un atlas custom en $XDG_DATA_HOME/tahuantinsuyu/ // Si hay un atlas custom en $XDG_DATA_HOME/cosmobiologia/
// atlas.tsv, lo cargamos y reemplazamos el atlas hardcoded // atlas.tsv, lo cargamos y reemplazamos el atlas hardcoded
// de 90 ciudades. Formato TSV: name<TAB>lat<TAB>lon<TAB>tz_min. // de 90 ciudades. Formato TSV: name<TAB>lat<TAB>lon<TAB>tz_min.
if let Some(atlas) = load_city_atlas_from_xdg() { if let Some(atlas) = load_city_atlas_from_xdg() {
@@ -419,7 +419,7 @@ impl Shell {
let result = cx let result = cx
.background_executor() .background_executor()
.spawn(async { .spawn(async {
brahman_sidecar::list_sessions_blocking("tahuantinsuyu-observer") brahman_sidecar::list_sessions_blocking("cosmobiologia-observer")
}) })
.await; .await;
let _ = this.update(cx, |this, cx| { let _ = this.update(cx, |this, cx| {
@@ -900,7 +900,7 @@ impl Shell {
.get("synastry") .get("synastry")
.and_then(|c| c.get("partner_chart_id")) .and_then(|c| c.get("partner_chart_id"))
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.and_then(|s| s.parse::<tahuantinsuyu_model::ChartId>().ok()) .and_then(|s| s.parse::<cosmobiologia_model::ChartId>().ok())
.and_then(|id| self.store.get_chart(id).ok()); .and_then(|id| self.store.get_chart(id).ok());
manual.or_else(|| self.find_synastry_partner_auto()) manual.or_else(|| self.find_synastry_partner_auto())
} }
@@ -920,7 +920,7 @@ impl Shell {
.get("composite") .get("composite")
.and_then(|c| c.get("partner_chart_id")) .and_then(|c| c.get("partner_chart_id"))
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.and_then(|s| s.parse::<tahuantinsuyu_model::ChartId>().ok()) .and_then(|s| s.parse::<cosmobiologia_model::ChartId>().ok())
.and_then(|id| self.store.get_chart(id).ok()); .and_then(|id| self.store.get_chart(id).ok());
manual.or_else(|| self.find_synastry_partner_auto()) manual.or_else(|| self.find_synastry_partner_auto())
} }
@@ -1176,7 +1176,7 @@ impl Shell {
} }
/// Recompone la carta actual + escribe el SVG a un archivo en /// Recompone la carta actual + escribe el SVG a un archivo en
/// `$XDG_DATA_HOME/tahuantinsuyu/exports/<label>_<short_id>.svg`. /// `$XDG_DATA_HOME/cosmobiologia/exports/<label>_<short_id>.svg`.
/// Logea la ruta a stderr — futuro: file save dialog GPUI. /// Logea la ruta a stderr — futuro: file save dialog GPUI.
fn export_current_to_svg(&self) { fn export_current_to_svg(&self) {
let Some(chart) = self.current_chart.as_ref() else { let Some(chart) = self.current_chart.as_ref() else {
@@ -1198,7 +1198,7 @@ impl Shell {
} }
}; };
let svg = svg_export::render_to_svg(&render); let svg = svg_export::render_to_svg(&render);
let dir = directories::ProjectDirs::from("net", "gioser", "tahuantinsuyu") let dir = directories::ProjectDirs::from("net", "gioser", "cosmobiologia")
.map(|d| d.data_dir().join("exports")) .map(|d| d.data_dir().join("exports"))
.unwrap_or_else(|| std::path::PathBuf::from(".")); .unwrap_or_else(|| std::path::PathBuf::from("."));
if let Err(e) = std::fs::create_dir_all(&dir) { if let Err(e) = std::fs::create_dir_all(&dir) {
@@ -1344,7 +1344,7 @@ impl Shell {
eprintln!("[shell] save_transit: la carta activa es libre"); eprintln!("[shell] save_transit: la carta activa es libre");
return; return;
} }
match tahuantinsuyu_engine::compute_transit_chart(natal) { match cosmobiologia_engine::compute_transit_chart(natal) {
Ok((birth, instant_label)) => { Ok((birth, instant_label)) => {
let label = format!("{} transito · {}", natal.label, instant_label); let label = format!("{} transito · {}", natal.label, instant_label);
self.insert_derived_free_chart(natal.clone(), birth, label, cx); self.insert_derived_free_chart(natal.clone(), birth, label, cx);
@@ -1368,7 +1368,7 @@ impl Shell {
return; return;
} }
let age = self.module_age_or_current("progression"); let age = self.module_age_or_current("progression");
match tahuantinsuyu_engine::compute_progression_chart(natal, age) { match cosmobiologia_engine::compute_progression_chart(natal, age) {
Ok((birth, instant_label)) => { Ok((birth, instant_label)) => {
let label = format!( let label = format!(
"{} prog-{:.0}a · {}", "{} prog-{:.0}a · {}",
@@ -1434,7 +1434,7 @@ impl Shell {
// Pedimos al engine la fecha exacta del retorno. La engine // Pedimos al engine la fecha exacta del retorno. La engine
// expone `compute_planetary_return_chart` que devuelve un // expone `compute_planetary_return_chart` que devuelve un
// `StoredBirthData` listo para reusar como carta natal. // `StoredBirthData` listo para reusar como carta natal.
match tahuantinsuyu_engine::compute_planetary_return_chart( match cosmobiologia_engine::compute_planetary_return_chart(
natal, &body, age, shift_days, natal, &body, age, shift_days,
) { ) {
Ok((birth, instant_label)) => { Ok((birth, instant_label)) => {
@@ -1460,15 +1460,15 @@ impl Shell {
// Helpers de module_configs // Helpers de module_configs
// ===================================================================== // =====================================================================
// OUTER_RING_MODULES viene de tahuantinsuyu_engine — single source of // OUTER_RING_MODULES viene de cosmobiologia_engine — single source of
// truth. Shell y canvas leen del mismo slice. // truth. Shell y canvas leen del mismo slice.
/// Lee `$XDG_DATA_HOME/tahuantinsuyu/atlas.tsv` si existe y lo parsea /// Lee `$XDG_DATA_HOME/cosmobiologia/atlas.tsv` si existe y lo parsea
/// como atlas de ciudades. Devuelve `None` cuando no hay archivo o /// como atlas de ciudades. Devuelve `None` cuando no hay archivo o
/// quedó vacío después del parse — el tree cae al atlas hardcoded. /// quedó vacío después del parse — el tree cae al atlas hardcoded.
fn load_city_atlas_from_xdg() -> Option<Vec<tahuantinsuyu_tree::CityPreset>> { fn load_city_atlas_from_xdg() -> Option<Vec<cosmobiologia_tree::CityPreset>> {
let path = directories::ProjectDirs::from("net", "gioser", "tahuantinsuyu") let path = directories::ProjectDirs::from("net", "gioser", "cosmobiologia")
.map(|d| d.data_dir().join("atlas.tsv"))?; .map(|d| d.data_dir().join("atlas.tsv"))?;
if !path.exists() { if !path.exists() {
return None; return None;
@@ -1558,7 +1558,7 @@ fn unix_to_civil_utc(secs: i64) -> (i32, u32, u32, u32, u32, u32) {
/// Etiqueta breve para mostrar al elegir una carta en el picker: /// Etiqueta breve para mostrar al elegir una carta en el picker:
/// `"YYYY-MM-DD · Lugar"` cuando hay lugar, sino solo la fecha. /// `"YYYY-MM-DD · Lugar"` cuando hay lugar, sino solo la fecha.
fn format_birth_brief(birth: &tahuantinsuyu_model::StoredBirthData) -> String { fn format_birth_brief(birth: &cosmobiologia_model::StoredBirthData) -> String {
let date = format!("{:04}-{:02}-{:02}", birth.year, birth.month, birth.day); let date = format!("{:04}-{:02}-{:02}", birth.year, birth.month, birth.day);
match &birth.birthplace_label { match &birth.birthplace_label {
Some(p) if !p.is_empty() => format!("{} · {}", date, p), Some(p) if !p.is_empty() => format!("{} · {}", date, p),
@@ -1569,7 +1569,7 @@ fn format_birth_brief(birth: &tahuantinsuyu_model::StoredBirthData) -> String {
/// Edad en años decimales desde el nacimiento hasta el reloj actual. /// Edad en años decimales desde el nacimiento hasta el reloj actual.
/// Aproximación: ignora la TZ de nacimiento (no afecta a resolución de /// Aproximación: ignora la TZ de nacimiento (no afecta a resolución de
/// año) y usa una fracción de año tropical sobre los segundos Unix. /// año) y usa una fracción de año tropical sobre los segundos Unix.
fn current_age_years(birth: &tahuantinsuyu_model::StoredBirthData) -> f64 { fn current_age_years(birth: &cosmobiologia_model::StoredBirthData) -> f64 {
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
let now_secs = SystemTime::now() let now_secs = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
@@ -0,0 +1,15 @@
[package]
name = "cosmobiologia-canvas"
version = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
description = "Tahuantinsuyu — widget GPUI del canvas astrológico. Capas modulares, jog-dial perimetral, estado unificado."
[dependencies]
cosmobiologia-engine = { path = "../cosmobiologia-engine" }
cosmobiologia-model = { path = "../cosmobiologia-model" }
cosmobiologia-modules = { path = "../cosmobiologia-modules" }
cosmobiologia-render = { path = "../cosmobiologia-render" }
cosmobiologia-theme = { path = "../cosmobiologia-theme" }
yahweh-theme = { workspace = true }
gpui = { workspace = true }
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-canvas` — el widget GPUI del lienzo astrológico. //! `cosmobiologia-canvas` — el widget GPUI del lienzo astrológico.
//! //!
//! Modela el cielo como un lienzo de **geometría reactiva**: un estado //! Modela el cielo como un lienzo de **geometría reactiva**: un estado
//! unificado [`CanvasState`] guarda offsets de rotación, flags de //! unificado [`CanvasState`] guarda offsets de rotación, flags de
@@ -40,9 +40,9 @@ use gpui::{
Window, canvas, div, hsla, point, prelude::*, px, Window, canvas, div, hsla, point, prelude::*, px,
}; };
use tahuantinsuyu_engine::{Geometry, Layer, LayerKind, OUTER_RING_MODULES, RenderModel}; use cosmobiologia_engine::{Geometry, Layer, LayerKind, OUTER_RING_MODULES, RenderModel};
use tahuantinsuyu_model::{ChartId, ContactId, GroupId}; use cosmobiologia_model::{ChartId, ContactId, GroupId};
use tahuantinsuyu_theme::{AspectKind as TAspectKind, AstroPalette, Element, Planet}; use cosmobiologia_theme::{AspectKind as TAspectKind, AstroPalette, Element, Planet};
use yahweh_theme::Theme; use yahweh_theme::Theme;
// ===================================================================== // =====================================================================
@@ -1808,11 +1808,11 @@ fn format_offset(minutes: i64) -> String {
// Painting // Painting
// ===================================================================== // =====================================================================
// `Radii` + helpers migraron a `tahuantinsuyu-render` (crate // `Radii` + helpers migraron a `cosmobiologia-render` (crate
// agnóstico de surface, compila a WASM y nativo). Re-export para // agnóstico de surface, compila a WASM y nativo). Re-export para
// que el código del canvas siga refiriendo `Radii` sin cambiar // que el código del canvas siga refiriendo `Radii` sin cambiar
// imports en cada call site. // imports en cada call site.
use tahuantinsuyu_render::Radii; use cosmobiologia_render::Radii;
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
// `hover_focus`: symbol del planeta hovereado en este frame (si lo // `hover_focus`: symbol del planeta hovereado en este frame (si lo
@@ -2482,8 +2482,8 @@ fn dist_point_segment(px: f32, py: f32, ax: f32, ay: f32, bx: f32, by: f32) -> f
(dx2 * dx2 + dy2 * dy2).sqrt() (dx2 * dx2 + dy2 * dy2).sqrt()
} }
// `polar_to_screen` se importa desde `tahuantinsuyu-render`. // `polar_to_screen` se importa desde `cosmobiologia-render`.
use tahuantinsuyu_render::polar_to_screen; use cosmobiologia_render::polar_to_screen;
fn centered_glyph( fn centered_glyph(
x: f32, x: f32,
@@ -2558,14 +2558,14 @@ fn body_disk_base(module_id: &str, kind: LayerKind, view_scale: f32) -> f32 {
base * view_scale base * view_scale
} }
// `spread_angles` y `find_clusters` migraron a `tahuantinsuyu-render`. // `spread_angles` y `find_clusters` migraron a `cosmobiologia-render`.
use tahuantinsuyu_render::{find_clusters, spread_angles}; use cosmobiologia_render::{find_clusters, spread_angles};
// `format_coord_compact` migró a `tahuantinsuyu-render`. // `format_coord_compact` migró a `cosmobiologia-render`.
use tahuantinsuyu_render::format_coord_compact; use cosmobiologia_render::format_coord_compact;
// Los tests de `spread_angles`, `find_clusters` y // Los tests de `spread_angles`, `find_clusters` y
// `format_coord_compact` viven ahora en `tahuantinsuyu-render::math` // `format_coord_compact` viven ahora en `cosmobiologia-render::math`
// junto a sus implementaciones. // junto a sus implementaciones.
/// Pill pequeña con un coord ("14°♈") junto al glyph de un planeta /// Pill pequeña con un coord ("14°♈") junto al glyph de un planeta
@@ -1,5 +1,5 @@
[package] [package]
name = "tahuantinsuyu-card" name = "cosmobiologia-card"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
@@ -8,8 +8,8 @@ description = "Tahuantinsuyu — Tarjeta de Presentación brahman + spawn del si
[dependencies] [dependencies]
brahman-card = { path = "../../../core/brahman-card" } brahman-card = { path = "../../../core/brahman-card" }
brahman-sidecar = { path = "../../../shared/brahman-sidecar" } brahman-sidecar = { path = "../../../shared/brahman-sidecar" }
tahuantinsuyu-engine = { path = "../tahuantinsuyu-engine" } cosmobiologia-engine = { path = "../cosmobiologia-engine" }
tahuantinsuyu-model = { path = "../tahuantinsuyu-model" } cosmobiologia-model = { path = "../cosmobiologia-model" }
ulid = { workspace = true } ulid = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
postcard = { workspace = true } postcard = { workspace = true }
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-card` — Tarjeta de Presentación + sidecar de la app. //! `cosmobiologia-card` — Tarjeta de Presentación + sidecar de la app.
//! //!
//! Cualquier binario que levante Tahuantinsuyu llama [`spawn_sidecar`] //! Cualquier binario que levante Tahuantinsuyu llama [`spawn_sidecar`]
//! antes de abrir la ventana GPUI. La lógica de thread / tokio / //! antes de abrir la ventana GPUI. La lógica de thread / tokio /
@@ -19,7 +19,7 @@ use brahman_card::{
use ulid::Ulid; use ulid::Ulid;
/// Label canónico — coincide con el binario y aparece en `ListEntes`. /// Label canónico — coincide con el binario y aparece en `ListEntes`.
pub const LABEL: &str = "brahman.tahuantinsuyu"; pub const LABEL: &str = "brahman.cosmobiologia";
/// Spawn fire-and-forget. Si el Init no está corriendo, el sidecar /// Spawn fire-and-forget. Si el Init no está corriendo, el sidecar
/// loggea y termina; la app sigue ejecutándose standalone. /// loggea y termina; la app sigue ejecutándose standalone.
@@ -56,7 +56,7 @@ pub fn build_card() -> Card {
flow: Flows { flow: Flows {
// Recibe peticiones de cómputo (carta natal, transit, etc.) // Recibe peticiones de cómputo (carta natal, transit, etc.)
// serializadas como JSON. La forma exacta la define // serializadas como JSON. La forma exacta la define
// `tahuantinsuyu-engine`. // `cosmobiologia-engine`.
input: vec![Flow { input: vec![Flow {
name: "chart-request".into(), name: "chart-request".into(),
ty: TypeRef::Primitive { ty: TypeRef::Primitive {
@@ -24,17 +24,17 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tahuantinsuyu_engine::{compose_with_options, NatalOptions, RenderModel}; use cosmobiologia_engine::{compose_with_options, NatalOptions, RenderModel};
use tahuantinsuyu_model::{Chart, ChartId, ChartKind, ContactId, StoredBirthData, StoredChartConfig}; use cosmobiologia_model::{Chart, ChartId, ChartKind, ContactId, StoredBirthData, StoredChartConfig};
use thiserror::Error; use thiserror::Error;
use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::{UnixListener, UnixStream}; use tokio::net::{UnixListener, UnixStream};
use tracing::{debug, error, info, warn}; use tracing::{debug, error, info, warn};
/// Path canónico del service socket. Usa `XDG_RUNTIME_DIR` si está /// Path canónico del service socket. Usa `XDG_RUNTIME_DIR` si está
/// (por usuario, no persistente), sino cae a `/tmp/tahuantinsuyu.sock`. /// (por usuario, no persistente), sino cae a `/tmp/cosmobiologia.sock`.
pub fn default_service_socket() -> PathBuf { pub fn default_service_socket() -> PathBuf {
if let Some(rt) = directories::ProjectDirs::from("net", "gioser", "tahuantinsuyu") { if let Some(rt) = directories::ProjectDirs::from("net", "gioser", "cosmobiologia") {
// ProjectDirs no expone runtime_dir directo en todas las // ProjectDirs no expone runtime_dir directo en todas las
// plataformas — usamos cache_dir como fallback estable. // plataformas — usamos cache_dir como fallback estable.
let mut p = rt.cache_dir().to_path_buf(); let mut p = rt.cache_dir().to_path_buf();
@@ -42,7 +42,7 @@ pub fn default_service_socket() -> PathBuf {
p.push("service.sock"); p.push("service.sock");
return p; return p;
} }
PathBuf::from("/tmp/tahuantinsuyu.sock") PathBuf::from("/tmp/cosmobiologia.sock")
} }
// ===================================================================== // =====================================================================
@@ -107,7 +107,7 @@ pub async fn serve(socket_path: PathBuf) -> Result<(), ServiceError> {
let _ = std::fs::remove_file(&socket_path); let _ = std::fs::remove_file(&socket_path);
let listener = UnixListener::bind(&socket_path)?; let listener = UnixListener::bind(&socket_path)?;
info!(socket = %socket_path.display(), "tahuantinsuyu service socket arriba"); info!(socket = %socket_path.display(), "cosmobiologia service socket arriba");
loop { loop {
let (stream, _addr) = listener.accept().await?; let (stream, _addr) = listener.accept().await?;
@@ -221,7 +221,7 @@ async fn read_frame<T: for<'de> Deserialize<'de>>(
/// thread termina. El binario GUI sigue funcionando standalone. /// thread termina. El binario GUI sigue funcionando standalone.
pub fn spawn_service_thread(socket_path: PathBuf) { pub fn spawn_service_thread(socket_path: PathBuf) {
std::thread::Builder::new() std::thread::Builder::new()
.name("tahuantinsuyu-service".into()) .name("cosmobiologia-service".into())
.spawn(move || { .spawn(move || {
let rt = match tokio::runtime::Builder::new_current_thread() let rt = match tokio::runtime::Builder::new_current_thread()
.enable_io() .enable_io()
@@ -1,13 +1,13 @@
[package] [package]
name = "tahuantinsuyu-engine" name = "cosmobiologia-engine"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
description = "Tahuantinsuyu — bridge entre el modelo agnóstico y eternal-astrology. Produce RenderModel agnóstico para el canvas." description = "Tahuantinsuyu — bridge entre el modelo agnóstico y eternal-astrology. Produce RenderModel agnóstico para el canvas."
[dependencies] [dependencies]
tahuantinsuyu-model = { path = "../tahuantinsuyu-model" } cosmobiologia-model = { path = "../cosmobiologia-model" }
tahuantinsuyu-render = { path = "../tahuantinsuyu-render" } cosmobiologia-render = { path = "../cosmobiologia-render" }
serde = { workspace = true } serde = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
@@ -1,4 +1,4 @@
//! Bridge real: `tahuantinsuyu_model::Chart` → eternal_astrology → [`RenderModel`]. //! Bridge real: `cosmobiologia_model::Chart` → eternal_astrology → [`RenderModel`].
//! //!
//! La sesión de efemérides VSOP2013 es **compartida globalmente** vía //! La sesión de efemérides VSOP2013 es **compartida globalmente** vía
//! `OnceLock` — abrirla cuesta unos cuantos ms (carga de las series en //! `OnceLock` — abrirla cuesta unos cuantos ms (carga de las series en
@@ -17,7 +17,7 @@ use eternal_astrology::{
}; };
use eternal_sky::{Ayanamsha, Body, EphemerisSession, Instant as ESInstant, Observer, SessionConfig}; use eternal_sky::{Ayanamsha, Body, EphemerisSession, Instant as ESInstant, Observer, SessionConfig};
use tahuantinsuyu_model::{Chart, HouseSystem, StoredChartConfig, Zodiac}; use cosmobiologia_model::{Chart, HouseSystem, StoredChartConfig, Zodiac};
use crate::dignity::essential_dignity; use crate::dignity::essential_dignity;
use crate::{ use crate::{
@@ -1031,7 +1031,7 @@ pub fn compute_planetary_return_chart(
body_str: &str, body_str: &str,
target_age_years: f64, target_age_years: f64,
shift_days: i64, shift_days: i64,
) -> Result<(tahuantinsuyu_model::StoredBirthData, String), EngineError> { ) -> Result<(cosmobiologia_model::StoredBirthData, String), EngineError> {
let (birth_e, config_e, _observer) = build_eternal_inputs(chart, 0)?; let (birth_e, config_e, _observer) = build_eternal_inputs(chart, 0)?;
let session = session()?; let session = session()?;
let natal = NatalChart::compute(&birth_e, &config_e, session) let natal = NatalChart::compute(&birth_e, &config_e, session)
@@ -1068,7 +1068,7 @@ pub fn compute_planetary_return_chart(
let (year, month, day, hour, minute, second) = parse_iso8601_components(&iso) let (year, month, day, hour, minute, second) = parse_iso8601_components(&iso)
.ok_or_else(|| EngineError::Eternal(format!("iso8601 inválido: {}", iso)))?; .ok_or_else(|| EngineError::Eternal(format!("iso8601 inválido: {}", iso)))?;
let stored = tahuantinsuyu_model::StoredBirthData { let stored = cosmobiologia_model::StoredBirthData {
year, year,
month, month,
day, day,
@@ -1099,13 +1099,13 @@ pub fn compute_planetary_return_chart(
/// en este instante anclado al lugar de nacimiento del sujeto. /// en este instante anclado al lugar de nacimiento del sujeto.
pub fn compute_transit_chart( pub fn compute_transit_chart(
chart: &Chart, chart: &Chart,
) -> Result<(tahuantinsuyu_model::StoredBirthData, String), EngineError> { ) -> Result<(cosmobiologia_model::StoredBirthData, String), EngineError> {
let now_iso = ESInstant::now().utc().to_iso8601(); let now_iso = ESInstant::now().utc().to_iso8601();
let (year, month, day, hour, minute, second) = let (year, month, day, hour, minute, second) =
parse_iso8601_components(&now_iso).ok_or_else(|| { parse_iso8601_components(&now_iso).ok_or_else(|| {
EngineError::Eternal(format!("iso8601 inválido para now(): {}", now_iso)) EngineError::Eternal(format!("iso8601 inválido para now(): {}", now_iso))
})?; })?;
let stored = tahuantinsuyu_model::StoredBirthData { let stored = cosmobiologia_model::StoredBirthData {
year, year,
month, month,
day, day,
@@ -1133,7 +1133,7 @@ pub fn compute_transit_chart(
pub fn compute_progression_chart( pub fn compute_progression_chart(
chart: &Chart, chart: &Chart,
target_age_years: f64, target_age_years: f64,
) -> Result<(tahuantinsuyu_model::StoredBirthData, String), EngineError> { ) -> Result<(cosmobiologia_model::StoredBirthData, String), EngineError> {
let (birth_e, _config_e, _observer) = build_eternal_inputs(chart, 0)?; let (birth_e, _config_e, _observer) = build_eternal_inputs(chart, 0)?;
let advance_seconds = target_age_years * 86400.0; // 1 día / año let advance_seconds = target_age_years * 86400.0; // 1 día / año
let advanced_utc = birth_e.instant.utc().add_seconds(advance_seconds); let advanced_utc = birth_e.instant.utc().add_seconds(advance_seconds);
@@ -1142,7 +1142,7 @@ pub fn compute_progression_chart(
parse_iso8601_components(&iso).ok_or_else(|| { parse_iso8601_components(&iso).ok_or_else(|| {
EngineError::Eternal(format!("iso8601 inválido: {}", iso)) EngineError::Eternal(format!("iso8601 inválido: {}", iso))
})?; })?;
let stored = tahuantinsuyu_model::StoredBirthData { let stored = cosmobiologia_model::StoredBirthData {
year, year,
month, month,
day, day,
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-engine` — bridge entre el modelo agnóstico y //! `cosmobiologia-engine` — bridge entre el modelo agnóstico y
//! `eternal-astrology`. //! `eternal-astrology`.
//! //!
//! Recibe un `Chart` del modelo + un `ChartKind` y devuelve un //! Recibe un `Chart` del modelo + un `ChartKind` y devuelve un
@@ -27,15 +27,15 @@
use thiserror::Error; use thiserror::Error;
pub use tahuantinsuyu_model::{Chart, ChartId, ChartKind}; pub use cosmobiologia_model::{Chart, ChartId, ChartKind};
// Los tipos del RenderModel viven en `tahuantinsuyu-render` (crate // Los tipos del RenderModel viven en `cosmobiologia-render` (crate
// agnóstico de surface — compila a WASM, lo consumen tanto el canvas // agnóstico de surface — compila a WASM, lo consumen tanto el canvas
// gpui como el cliente web). El engine los reexporta para mantener // gpui como el cliente web). El engine los reexporta para mantener
// compatibilidad con todos los call sites históricos // compatibilidad con todos los call sites históricos
// (`tahuantinsuyu_engine::Layer`, etc.) sin tener que cambiar // (`cosmobiologia_engine::Layer`, etc.) sin tener que cambiar
// imports en el shell, canvas, modules, tree, panel... // imports en el shell, canvas, modules, tree, panel...
pub use tahuantinsuyu_render::{ pub use cosmobiologia_render::{
AspectSummary, Geometry, Glyph, Layer, LayerKind, LineSeg, OverlayMeta, PointMark, AspectSummary, Geometry, Glyph, Layer, LayerKind, LineSeg, OverlayMeta, PointMark,
RenderModel, UranianGroup, OUTER_RING_MODULES, RenderModel, UranianGroup, OUTER_RING_MODULES,
}; };
@@ -62,7 +62,7 @@ pub enum EngineError {
#[error("bridge a eternal-astrology no disponible (recompilá con feature `eternal-bridge`)")] #[error("bridge a eternal-astrology no disponible (recompilá con feature `eternal-bridge`)")]
BridgeDisabled, BridgeDisabled,
#[error("model: {0}")] #[error("model: {0}")]
Model(#[from] tahuantinsuyu_model::ModelError), Model(#[from] cosmobiologia_model::ModelError),
#[error("eternal: {0}")] #[error("eternal: {0}")]
Eternal(String), Eternal(String),
#[error("kind {0:?} todavía no implementado")] #[error("kind {0:?} todavía no implementado")]
@@ -78,7 +78,7 @@ pub enum EngineError {
/// son **overlays adicionales**. /// son **overlays adicionales**.
/// ///
/// Cada variante mapea 1-a-1 con un Module declarado en /// Cada variante mapea 1-a-1 con un Module declarado en
/// `tahuantinsuyu-modules` por id string. Esto deja la engine como /// `cosmobiologia-modules` por id string. Esto deja la engine como
/// dueña única del cómputo (no depende del trait Module — los módulos /// dueña única del cómputo (no depende del trait Module — los módulos
/// son sólo metadata + UI controls). /// son sólo metadata + UI controls).
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -262,7 +262,7 @@ pub fn compute_planetary_return_chart(
body: &str, body: &str,
target_age_years: f64, target_age_years: f64,
shift_days: i64, shift_days: i64,
) -> Result<(tahuantinsuyu_model::StoredBirthData, String), EngineError> { ) -> Result<(cosmobiologia_model::StoredBirthData, String), EngineError> {
bridge::compute_planetary_return_chart(chart, body, target_age_years, shift_days) bridge::compute_planetary_return_chart(chart, body, target_age_years, shift_days)
} }
@@ -272,7 +272,7 @@ pub fn compute_planetary_return_chart(
#[cfg(feature = "eternal-bridge")] #[cfg(feature = "eternal-bridge")]
pub fn compute_transit_chart( pub fn compute_transit_chart(
chart: &Chart, chart: &Chart,
) -> Result<(tahuantinsuyu_model::StoredBirthData, String), EngineError> { ) -> Result<(cosmobiologia_model::StoredBirthData, String), EngineError> {
bridge::compute_transit_chart(chart) bridge::compute_transit_chart(chart)
} }
@@ -282,7 +282,7 @@ pub fn compute_transit_chart(
pub fn compute_progression_chart( pub fn compute_progression_chart(
chart: &Chart, chart: &Chart,
target_age_years: f64, target_age_years: f64,
) -> Result<(tahuantinsuyu_model::StoredBirthData, String), EngineError> { ) -> Result<(cosmobiologia_model::StoredBirthData, String), EngineError> {
bridge::compute_progression_chart(chart, target_age_years) bridge::compute_progression_chart(chart, target_age_years)
} }
@@ -361,7 +361,7 @@ const ZODIAC_GLYPHS: [&str; 12] = [
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use tahuantinsuyu_model::{ use cosmobiologia_model::{
Chart, ChartKind, ContactId, StoredBirthData, StoredChartConfig, Chart, ChartKind, ContactId, StoredBirthData, StoredChartConfig,
}; };
@@ -17,7 +17,7 @@ use std::hash::{Hash, Hasher};
use std::sync::{Arc, Mutex, OnceLock}; use std::sync::{Arc, Mutex, OnceLock};
use eternal_astrology::NatalChart; use eternal_astrology::NatalChart;
use tahuantinsuyu_model::{StoredBirthData, StoredChartConfig}; use cosmobiologia_model::{StoredBirthData, StoredChartConfig};
const CAPACITY: usize = 8; const CAPACITY: usize = 8;
@@ -17,7 +17,7 @@ use crate::{Geometry, LayerKind, RenderModel};
const VIEWBOX: f64 = 800.0; const VIEWBOX: f64 = 800.0;
const MARGIN: f64 = 40.0; const MARGIN: f64 = 40.0;
/// Radios normalizados — espejan los de `tahuantinsuyu-canvas`. /// Radios normalizados — espejan los de `cosmobiologia-canvas`.
const R_SIGN_OUTER: f64 = 1.00; const R_SIGN_OUTER: f64 = 1.00;
const R_SIGN_INNER: f64 = 0.88; const R_SIGN_INNER: f64 = 0.88;
const R_TRANSITS: f64 = 0.82; const R_TRANSITS: f64 = 0.82;
@@ -277,11 +277,11 @@ fn escape_xml(s: &str) -> String {
mod tests { mod tests {
use super::*; use super::*;
use crate::{compute_mock, ChartKind}; use crate::{compute_mock, ChartKind};
use tahuantinsuyu_model::{Chart, ContactId, StoredBirthData, StoredChartConfig}; use cosmobiologia_model::{Chart, ContactId, StoredBirthData, StoredChartConfig};
fn sample_chart() -> Chart { fn sample_chart() -> Chart {
Chart { Chart {
id: tahuantinsuyu_model::ChartId::new(), id: cosmobiologia_model::ChartId::new(),
contact_id: ContactId::new(), contact_id: ContactId::new(),
kind: ChartKind::Natal, kind: ChartKind::Natal,
label: "Test".into(), label: "Test".into(),
@@ -1,5 +1,5 @@
[package] [package]
name = "tahuantinsuyu-model" name = "cosmobiologia-model"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-model` — tipos agnósticos del estudio astrológico. //! `cosmobiologia-model` — tipos agnósticos del estudio astrológico.
//! //!
//! Esta es la capa de **datos puros**: no conoce GPUI, ni rusqlite, ni //! Esta es la capa de **datos puros**: no conoce GPUI, ni rusqlite, ni
//! `eternal-astrology`. Solo tipos `serde`-able que viajan entre la //! `eternal-astrology`. Solo tipos `serde`-able que viajan entre la
@@ -1,12 +1,12 @@
[package] [package]
name = "tahuantinsuyu-modules" name = "cosmobiologia-modules"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
description = "Tahuantinsuyu — registry de módulos astrológicos (Natal, Transit, Synastry, Uranian, …)." description = "Tahuantinsuyu — registry de módulos astrológicos (Natal, Transit, Synastry, Uranian, …)."
[dependencies] [dependencies]
tahuantinsuyu-model = { path = "../tahuantinsuyu-model" } cosmobiologia-model = { path = "../cosmobiologia-model" }
tahuantinsuyu-engine = { path = "../tahuantinsuyu-engine" } cosmobiologia-engine = { path = "../cosmobiologia-engine" }
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-modules` — registry de módulos astrológicos. //! `cosmobiologia-modules` — registry de módulos astrológicos.
//! //!
//! Cada tipo de astrología (natal, tránsito, progresión, sinastría, //! Cada tipo de astrología (natal, tránsito, progresión, sinastría,
//! Uraniano, …) es un **módulo** que declara: //! Uraniano, …) es un **módulo** que declara:
@@ -22,8 +22,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tahuantinsuyu_engine::Layer; use cosmobiologia_engine::Layer;
use tahuantinsuyu_model::{Chart, ChartKind}; use cosmobiologia_model::{Chart, ChartKind};
// ===================================================================== // =====================================================================
// Trait Module // Trait Module
@@ -185,7 +185,7 @@ impl Registry {
pub mod natal { pub mod natal {
use super::*; use super::*;
use tahuantinsuyu_engine::compute_mock; use cosmobiologia_engine::compute_mock;
pub struct NatalModule; pub struct NatalModule;
@@ -1,14 +1,14 @@
[package] [package]
name = "tahuantinsuyu-panel" name = "cosmobiologia-panel"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
description = "Tahuantinsuyu — panel de control inferior. Toggles, sliders y selectores por módulo de astrología." description = "Tahuantinsuyu — panel de control inferior. Toggles, sliders y selectores por módulo de astrología."
[dependencies] [dependencies]
tahuantinsuyu-model = { path = "../tahuantinsuyu-model" } cosmobiologia-model = { path = "../cosmobiologia-model" }
tahuantinsuyu-modules = { path = "../tahuantinsuyu-modules" } cosmobiologia-modules = { path = "../cosmobiologia-modules" }
tahuantinsuyu-theme = { path = "../tahuantinsuyu-theme" } cosmobiologia-theme = { path = "../cosmobiologia-theme" }
yahweh-theme = { workspace = true } yahweh-theme = { workspace = true }
gpui = { workspace = true } gpui = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
@@ -1,7 +1,7 @@
//! `tahuantinsuyu-panel` — control panel inferior de la app. //! `cosmobiologia-panel` — control panel inferior de la app.
//! //!
//! Lee los módulos disponibles para la carta activa (vía //! Lee los módulos disponibles para la carta activa (vía
//! [`tahuantinsuyu_modules::Registry::for_kind`]) y pinta sus //! [`cosmobiologia_modules::Registry::for_kind`]) y pinta sus
//! [`Control`]s como toggles / sliders / selects. Cada cambio emite //! [`Control`]s como toggles / sliders / selects. Cada cambio emite
//! [`PanelEvent`] que la app traduce a mutaciones de visibilidad sobre //! [`PanelEvent`] que la app traduce a mutaciones de visibilidad sobre
//! el canvas y al `module_configs` del shell. //! el canvas y al `module_configs` del shell.
@@ -29,8 +29,8 @@ use gpui::{
Window, canvas, div, prelude::*, px, Window, canvas, div, prelude::*, px,
}; };
use tahuantinsuyu_model::ChartKind; use cosmobiologia_model::ChartKind;
use tahuantinsuyu_modules::{Control, Registry, SelectOption}; use cosmobiologia_modules::{Control, Registry, SelectOption};
use yahweh_theme::Theme; use yahweh_theme::Theme;
// ===================================================================== // =====================================================================
@@ -1,12 +1,12 @@
[package] [package]
name = "tahuantinsuyu-render" name = "cosmobiologia-render"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
description = "Tahuantinsuyu — modelo y matemática de render agnósticos de surface. Compila a WASM y a nativo; el canvas gpui y el cliente web lo consumen para emitir las primitivas comunes de la rueda." description = "Tahuantinsuyu — modelo y matemática de render agnósticos de surface. Compila a WASM y a nativo; el canvas gpui y el cliente web lo consumen para emitir las primitivas comunes de la rueda."
[dependencies] [dependencies]
tahuantinsuyu-model = { path = "../tahuantinsuyu-model" } cosmobiologia-model = { path = "../cosmobiologia-model" }
serde = { workspace = true } serde = { workspace = true }
[lib] [lib]
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-render` — modelo y matemática de render //! `cosmobiologia-render` — modelo y matemática de render
//! **agnósticos de surface**. Lo consumen tanto el canvas gpui //! **agnósticos de surface**. Lo consumen tanto el canvas gpui
//! (nativo, render Vulkan/Metal) como el cliente web (WASM, render //! (nativo, render Vulkan/Metal) como el cliente web (WASM, render
//! SVG / Canvas2D). Cualquier mejora del layout / spread / cluster / //! SVG / Canvas2D). Cualquier mejora del layout / spread / cluster /
@@ -6,7 +6,7 @@
//! //!
//! ## Por qué un crate aparte //! ## Por qué un crate aparte
//! //!
//! `tahuantinsuyu-engine` arrastra `eternal-sky` (VSOP2013 + I/O de //! `cosmobiologia-engine` arrastra `eternal-sky` (VSOP2013 + I/O de
//! tablas) que **no compila a WASM** sin empaquetar 30+ MB de //! tablas) que **no compila a WASM** sin empaquetar 30+ MB de
//! efemérides. Los tipos del `RenderModel` en sí son serde puro y //! efemérides. Los tipos del `RenderModel` en sí son serde puro y
//! sí compilan a WASM — extraerlos a este crate libera al cliente //! sí compilan a WASM — extraerlos a este crate libera al cliente
@@ -28,7 +28,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub use tahuantinsuyu_model::{Chart, ChartId, ChartKind}; pub use cosmobiologia_model::{Chart, ChartId, ChartKind};
pub mod math; pub mod math;
@@ -1,12 +1,12 @@
[package] [package]
name = "tahuantinsuyu-store" name = "cosmobiologia-store"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
description = "Tahuantinsuyu — persistencia SQLite de groups / contacts / charts / module_state." description = "Tahuantinsuyu — persistencia SQLite de groups / contacts / charts / module_state."
[dependencies] [dependencies]
tahuantinsuyu-model = { path = "../tahuantinsuyu-model" } cosmobiologia-model = { path = "../cosmobiologia-model" }
rusqlite = { workspace = true } rusqlite = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-store` — persistencia SQLite del estudio astrológico. //! `cosmobiologia-store` — persistencia SQLite del estudio astrológico.
//! //!
//! Una sola conexión `rusqlite` envuelta en `Arc<Mutex>` para que la app //! Una sola conexión `rusqlite` envuelta en `Arc<Mutex>` para que la app
//! GPUI la comparta entre threads sin pelearse con el ownership. La //! GPUI la comparta entre threads sin pelearse con el ownership. La
@@ -7,7 +7,7 @@
//! //!
//! Patrón inspirado en `yahweh_provider_sqlite::SqliteDataProvider` pero //! Patrón inspirado en `yahweh_provider_sqlite::SqliteDataProvider` pero
//! con dominio propio (no extiende el `DataProvider` agnóstico — esa //! con dominio propio (no extiende el `DataProvider` agnóstico — esa
//! integración viene en `tahuantinsuyu-tree` que envuelve este store //! integración viene en `cosmobiologia-tree` que envuelve este store
//! detrás del trait de yahweh). //! detrás del trait de yahweh).
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
@@ -20,7 +20,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use rusqlite::{Connection, OptionalExtension, params}; use rusqlite::{Connection, OptionalExtension, params};
use thiserror::Error; use thiserror::Error;
use tahuantinsuyu_model::{ use cosmobiologia_model::{
Chart, ChartId, ChartKind, Contact, ContactId, Group, GroupId, ModuleState, StoredBirthData, Chart, ChartId, ChartKind, Contact, ContactId, Group, GroupId, ModuleState, StoredBirthData,
StoredChartConfig, StoredChartConfig,
}; };
@@ -38,7 +38,7 @@ pub enum StoreError {
#[error("ulid decode: {0}")] #[error("ulid decode: {0}")]
UlidDecode(#[from] ulid::DecodeError), UlidDecode(#[from] ulid::DecodeError),
#[error("model invariant: {0}")] #[error("model invariant: {0}")]
Model(#[from] tahuantinsuyu_model::ModelError), Model(#[from] cosmobiologia_model::ModelError),
#[error("not found: {0}")] #[error("not found: {0}")]
NotFound(String), NotFound(String),
} }
@@ -622,7 +622,7 @@ fn now_ms() -> i64 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use tahuantinsuyu_model::{ModuleState, StoredBirthData, StoredChartConfig}; use cosmobiologia_model::{ModuleState, StoredBirthData, StoredChartConfig};
#[test] #[test]
fn open_and_migrate() { fn open_and_migrate() {
@@ -1,5 +1,5 @@
[package] [package]
name = "tahuantinsuyu-theme" name = "cosmobiologia-theme"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-theme` — paleta simbólica + presets místicos. //! `cosmobiologia-theme` — paleta simbólica + presets místicos.
//! //!
//! Una capa fina sobre [`yahweh_theme::Theme`]: el theme base aporta los //! Una capa fina sobre [`yahweh_theme::Theme`]: el theme base aporta los
//! slots de panel/foreground/accent; nosotros agregamos paletas //! slots de panel/foreground/accent; nosotros agregamos paletas
@@ -1,13 +1,13 @@
[package] [package]
name = "tahuantinsuyu-tree" name = "cosmobiologia-tree"
version = { workspace = true } version = { workspace = true }
edition = { workspace = true } edition = { workspace = true }
license = { workspace = true } license = { workspace = true }
description = "Tahuantinsuyu — explorador izquierdo (Groups/Contacts/Charts) sobre yahweh-widget-tree." description = "Tahuantinsuyu — explorador izquierdo (Groups/Contacts/Charts) sobre yahweh-widget-tree."
[dependencies] [dependencies]
tahuantinsuyu-model = { path = "../tahuantinsuyu-model" } cosmobiologia-model = { path = "../cosmobiologia-model" }
tahuantinsuyu-store = { path = "../tahuantinsuyu-store" } cosmobiologia-store = { path = "../cosmobiologia-store" }
yahweh-theme = { workspace = true } yahweh-theme = { workspace = true }
yahweh-widget-tree = { workspace = true } yahweh-widget-tree = { workspace = true }
yahweh-widget-text-input = { path = "../../ui_engine/widgets/text_input" } yahweh-widget-text-input = { path = "../../ui_engine/widgets/text_input" }
@@ -1,4 +1,4 @@
//! `tahuantinsuyu-tree` — explorador jerárquico Groups → Contacts → Charts. //! `cosmobiologia-tree` — explorador jerárquico Groups → Contacts → Charts.
//! //!
//! Envuelve [`yahweh_widget_tree::TreeView`] con la lógica de dominio //! Envuelve [`yahweh_widget_tree::TreeView`] con la lógica de dominio
//! de Tahuantinsuyu. Los `RowId` codifican el tipo con prefijo: //! de Tahuantinsuyu. Los `RowId` codifican el tipo con prefijo:
@@ -29,11 +29,11 @@ use gpui::{
SharedString, Window, div, hsla, prelude::*, px, SharedString, Window, div, hsla, prelude::*, px,
}; };
use tahuantinsuyu_model::{ use cosmobiologia_model::{
ChartId, ChartKind, ContactId, FreeChartId, GroupId, StoredBirthData, StoredChartConfig, ChartId, ChartKind, ContactId, FreeChartId, GroupId, StoredBirthData, StoredChartConfig,
TimeCertainty, TreeSelection, TimeCertainty, TreeSelection,
}; };
use tahuantinsuyu_store::Store; use cosmobiologia_store::Store;
use yahweh_theme::Theme; use yahweh_theme::Theme;
use yahweh_widget_text_input::{TextInput, TextInputEvent}; use yahweh_widget_text_input::{TextInput, TextInputEvent};
use yahweh_widget_tree::{RowId, RowKind, TreeEvent as InnerTreeEvent, TreeRow, TreeView}; use yahweh_widget_tree::{RowId, RowKind, TreeEvent as InnerTreeEvent, TreeRow, TreeView};
@@ -270,7 +270,7 @@ pub struct CityPreset {
/// Atlas hardcoded — 90 ciudades canónicas que cubren la mayoría de /// Atlas hardcoded — 90 ciudades canónicas que cubren la mayoría de
/// casos de uso. El usuario puede sobrescribirlas pasando un atlas /// casos de uso. El usuario puede sobrescribirlas pasando un atlas
/// custom vía [`TahuantinsuyuTree::set_city_atlas`] (típicamente /// custom vía [`TahuantinsuyuTree::set_city_atlas`] (típicamente
/// cargado desde `$XDG_DATA_HOME/tahuantinsuyu/atlas.tsv`). /// cargado desde `$XDG_DATA_HOME/cosmobiologia/atlas.tsv`).
pub fn default_city_presets() -> Vec<CityPreset> { pub fn default_city_presets() -> Vec<CityPreset> {
vec![ vec![
// Latinoamérica // Latinoamérica
@@ -421,7 +421,7 @@ impl TahuantinsuyuTree {
pub fn new(store: Store, cx: &mut Context<'_, Self>) -> Self { pub fn new(store: Store, cx: &mut Context<'_, Self>) -> Self {
cx.observe_global::<Theme>(|_, cx| cx.notify()).detach(); cx.observe_global::<Theme>(|_, cx| cx.notify()).detach();
let inner = cx.new(|cx| TreeView::new("tahuantinsuyu-tree", cx)); let inner = cx.new(|cx| TreeView::new("cosmobiologia-tree", cx));
cx.subscribe(&inner, |this: &mut Self, _, ev, cx| { cx.subscribe(&inner, |this: &mut Self, _, ev, cx| {
this.on_inner(ev, cx); this.on_inner(ev, cx);
}) })
@@ -1507,7 +1507,7 @@ fn parse_field<T: std::str::FromStr>(s: &str, field: &str) -> Result<T, String>
// Lookups auxiliares (DFS por la jerarquía) // Lookups auxiliares (DFS por la jerarquía)
// ===================================================================== // =====================================================================
fn find_group_name(roots: &[tahuantinsuyu_model::Group], store: &Store, id: GroupId) -> Option<String> { fn find_group_name(roots: &[cosmobiologia_model::Group], store: &Store, id: GroupId) -> Option<String> {
for g in roots { for g in roots {
if g.id == id { if g.id == id {
return Some(g.name.clone()); return Some(g.name.clone());
@@ -1522,7 +1522,7 @@ fn find_group_name(roots: &[tahuantinsuyu_model::Group], store: &Store, id: Grou
} }
fn find_contact_name( fn find_contact_name(
in_group: &[tahuantinsuyu_model::Contact], in_group: &[cosmobiologia_model::Contact],
store: &Store, store: &Store,
id: ContactId, id: ContactId,
) -> Option<String> { ) -> Option<String> {
@@ -1541,7 +1541,7 @@ fn find_contact_name(
} }
fn find_contact_in_groups( fn find_contact_in_groups(
groups: &[tahuantinsuyu_model::Group], groups: &[cosmobiologia_model::Group],
store: &Store, store: &Store,
id: ContactId, id: ContactId,
) -> Option<String> { ) -> Option<String> {
@@ -1602,7 +1602,7 @@ impl Render for TahuantinsuyuTree {
.child(self.search_input.clone()); .child(self.search_input.clone());
let mut root = div() let mut root = div()
.id("tahuantinsuyu-tree-root") .id("cosmobiologia-tree-root")
.size_full() .size_full()
.relative() .relative()
.bg(theme.bg_panel.clone()) .bg(theme.bg_panel.clone())
@@ -1,15 +0,0 @@
[package]
name = "tahuantinsuyu-canvas"
version = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
description = "Tahuantinsuyu — widget GPUI del canvas astrológico. Capas modulares, jog-dial perimetral, estado unificado."
[dependencies]
tahuantinsuyu-engine = { path = "../tahuantinsuyu-engine" }
tahuantinsuyu-model = { path = "../tahuantinsuyu-model" }
tahuantinsuyu-modules = { path = "../tahuantinsuyu-modules" }
tahuantinsuyu-render = { path = "../tahuantinsuyu-render" }
tahuantinsuyu-theme = { path = "../tahuantinsuyu-theme" }
yahweh-theme = { workspace = true }
gpui = { workspace = true }