chore: rename tahuantinsuyu → cosmobiologia

Rename clean del proyecto astrológico antes de empezar el módulo
web (fase 2 = server axum, fase 3 = cliente WASM). Hacerlo ahora
ahorra refactor de URLs, package.json, paths de assets HTML y
deploy configs que aparecerían con el nombre en cuanto exista el
server.

Mecánica:
- `git mv` de los 10 crates de módulo + 2 apps:
  * `crates/modules/tahuantinsuyu/` → `cosmobiologia/`
  * `crates/modules/tahuantinsuyu/tahuantinsuyu-*` →
    `cosmobiologia/cosmobiologia-*`
  * `crates/apps/tahuantinsuyu` y `tahuantinsuyu-cli` análogos.
- Sed sobre todos los `.rs` y `.toml`: `tahuantinsuyu` →
  `cosmobiologia` (cubre crate names, deps paths, use
  statements, ProjectDirs literals, binary names).
- Workspace `Cargo.toml`: members con paths nuevos.
- Memoria del proyecto (`~/.claude/.../memory/project_*.md`)
  actualizada.

Cero leftovers: `grep -rn tahuantinsuyu --include="*.rs"
--include="*.toml" crates/` devuelve vacío.

DB & XDG: clean slate. La nueva app arranca con DB vacía en
`$XDG_DATA_HOME/cosmobiologia/charts.db`. Si tenías cartas
guardadas, viven todavía en `~/.local/share/tahuantinsuyu/` —
las podés migrar manualmente con un `cp`.

IDs UI inalterados: el prefijo `tts-` de gpui ElementIds queda
igual (cosmético, no afecta funcionalidad). Cambiarlo a `cb-`
ahora sería 3-4 líneas más de sed pero ningún beneficio
operativo.

Tests: 20 verdes (10 shell + 10 render math). Compila full:
`cargo check -p cosmobiologia` OK.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-19 00:45:48 +00:00
parent 9084cf4b79
commit 06a1ca11ce
34 changed files with 325 additions and 315 deletions
@@ -1,18 +1,18 @@
[package]
name = "tahuantinsuyu-cli"
name = "cosmobiologia-cli"
version = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
description = "Tahuantinsuyu — CLI cliente del service socket. Pide cómputos de cartas sin abrir la GUI."
[dependencies]
tahuantinsuyu-card = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-card" }
tahuantinsuyu-model = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-model" }
cosmobiologia-card = { path = "../../modules/cosmobiologia/cosmobiologia-card" }
cosmobiologia-model = { path = "../../modules/cosmobiologia/cosmobiologia-model" }
clap = { workspace = true }
tokio = { workspace = true }
serde_json = { workspace = true }
anyhow = { workspace = true }
[[bin]]
name = "tahuantinsuyu-cli"
name = "cosmobiologia-cli"
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,
//! scripts y para verificar end-to-end que el data plane brahman está
//! sirviendo. Conecta al socket que la app GUI expone (default
//! `$XDG_CACHE_HOME/tahuantinsuyu/service.sock`).
//! `$XDG_CACHE_HOME/cosmobiologia/service.sock`).
//!
//! ## Comandos
//!
@@ -15,7 +15,7 @@
//! ## Ejemplo
//!
//! ```bash
//! cargo run -p tahuantinsuyu-cli -- natal \
//! cargo run -p cosmobiologia-cli -- natal \
//! --year 1987 --month 3 --day 14 \
//! --hour 5 --minute 22 --tz-min -240 \
//! --lat 10.4806 --lon -66.9036 \
@@ -26,12 +26,12 @@ use std::path::PathBuf;
use anyhow::{anyhow, Context, Result};
use clap::{Parser, Subcommand};
use tahuantinsuyu_card::service::{self, ComputeRequest, ComputeResponse};
use tahuantinsuyu_model::{StoredBirthData, StoredChartConfig};
use cosmobiologia_card::service::{self, ComputeRequest, ComputeResponse};
use cosmobiologia_model::{StoredBirthData, StoredChartConfig};
#[derive(Parser)]
#[command(
name = "tahuantinsuyu-cli",
name = "cosmobiologia-cli",
version,
about = "Cliente del service socket de Tahuantinsuyu."
)]
@@ -1,20 +1,20 @@
[package]
name = "tahuantinsuyu"
name = "cosmobiologia"
version = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
description = "Tahuantinsuyu — estudio profesional de astrología. Tree + canvas + panel sobre yahweh + eternal-astrology."
[dependencies]
tahuantinsuyu-card = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-card" }
tahuantinsuyu-canvas = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-canvas" }
tahuantinsuyu-engine = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-engine" }
tahuantinsuyu-model = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-model" }
tahuantinsuyu-modules = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-modules" }
tahuantinsuyu-panel = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-panel" }
tahuantinsuyu-store = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-store" }
tahuantinsuyu-theme = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-theme" }
tahuantinsuyu-tree = { path = "../../modules/tahuantinsuyu/tahuantinsuyu-tree" }
cosmobiologia-card = { path = "../../modules/cosmobiologia/cosmobiologia-card" }
cosmobiologia-canvas = { path = "../../modules/cosmobiologia/cosmobiologia-canvas" }
cosmobiologia-engine = { path = "../../modules/cosmobiologia/cosmobiologia-engine" }
cosmobiologia-model = { path = "../../modules/cosmobiologia/cosmobiologia-model" }
cosmobiologia-modules = { path = "../../modules/cosmobiologia/cosmobiologia-modules" }
cosmobiologia-panel = { path = "../../modules/cosmobiologia/cosmobiologia-panel" }
cosmobiologia-store = { path = "../../modules/cosmobiologia/cosmobiologia-store" }
cosmobiologia-theme = { path = "../../modules/cosmobiologia/cosmobiologia-theme" }
cosmobiologia-tree = { path = "../../modules/cosmobiologia/cosmobiologia-tree" }
brahman-sidecar = { path = "../../shared/brahman-sidecar" }
yahweh-core = { workspace = true }
@@ -31,5 +31,5 @@ serde_json = { workspace = true }
gpui = { workspace = true, features = ["test-support"] }
[[bin]]
name = "tahuantinsuyu"
name = "cosmobiologia"
path = "src/main.rs"
@@ -1,10 +1,10 @@
//! Tahuantinsuyu — binario standalone.
//!
//! 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).
//! 2. Abre la DB SQLite en `$XDG_DATA_HOME/tahuantinsuyu/charts.db`
//! (fallback a `~/.local/share/tahuantinsuyu/charts.db`).
//! 2. Abre la DB SQLite en `$XDG_DATA_HOME/cosmobiologia/charts.db`
//! (fallback a `~/.local/share/cosmobiologia/charts.db`).
//! 3. Levanta GPUI con [`yahweh_theme::Theme::install_default`].
//! 4. Compone el shell: [`Shell`] dueño del tree (izq), canvas (centro)
//! y panel (abajo). Cablea las suscripciones cross-widget.
@@ -33,7 +33,7 @@ use gpui::{
WindowOptions, px, size,
};
use tahuantinsuyu_store::Store;
use cosmobiologia_store::Store;
use yahweh_theme::Theme;
use crate::shell::Shell;
@@ -43,14 +43,14 @@ const APP_TITLE: &str = "Tahuantinsuyu";
fn main() {
// 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
// módulos brahman pueden conectar y pedir cómputos de cartas
// natales sin GUI. Si el bind falla (socket ya tomado, sin
// permisos), loggea warn y la app sigue corriendo standalone.
let service_socket = tahuantinsuyu_card::service::default_service_socket();
eprintln!("[tahuantinsuyu] service socket → {}", service_socket.display());
tahuantinsuyu_card::service::spawn_service_thread(service_socket);
let service_socket = cosmobiologia_card::service::default_service_socket();
eprintln!("[cosmobiologia] service socket → {}", service_socket.display());
cosmobiologia_card::service::spawn_service_thread(service_socket);
// DB en directorio de datos del usuario.
let db_path = resolve_db_path();
@@ -58,7 +58,7 @@ fn main() {
Ok(s) => s,
Err(e) => {
eprintln!(
"[tahuantinsuyu] no se pudo abrir la DB en {:?}: {} — usando memoria",
"[cosmobiologia] no se pudo abrir la DB en {:?}: {} — usando memoria",
db_path, e
);
Store::in_memory().expect("in-memory store")
@@ -86,7 +86,7 @@ fn main() {
}
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 _ = std::fs::create_dir_all(&dir);
return dir.join(DB_FILENAME);
@@ -28,20 +28,20 @@ use gpui::{
Window, div, prelude::*, px,
};
use tahuantinsuyu_canvas::{
use cosmobiologia_canvas::{
AstrologyCanvas, CanvasEvent, CanvasMode, ThumbnailItem, ThumbnailScope,
};
use tahuantinsuyu_engine::{
use cosmobiologia_engine::{
LayerKind, NatalOptions, OUTER_RING_MODULES, PipelineRequest, compose_with_options,
svg_export,
};
use tahuantinsuyu_model::{
use cosmobiologia_model::{
Chart, ChartId, ChartKind, ContactId, FreeChartId, ModuleState, StoredBirthData,
StoredChartConfig, TreeSelection,
};
use tahuantinsuyu_panel::{ChartOption, ControlPanel, PanelEvent};
use tahuantinsuyu_store::Store;
use tahuantinsuyu_tree::{
use cosmobiologia_panel::{ChartOption, ControlPanel, PanelEvent};
use cosmobiologia_store::Store;
use cosmobiologia_tree::{
parse_city_atlas_tsv, FreeChartEntry, TahuantinsuyuTree, TreeEvent,
};
use yahweh_core::{LayoutDirection, NodeId};
@@ -147,7 +147,7 @@ impl Shell {
let tree = cx.new(|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
// de 90 ciudades. Formato TSV: name<TAB>lat<TAB>lon<TAB>tz_min.
if let Some(atlas) = load_city_atlas_from_xdg() {
@@ -419,7 +419,7 @@ impl Shell {
let result = cx
.background_executor()
.spawn(async {
brahman_sidecar::list_sessions_blocking("tahuantinsuyu-observer")
brahman_sidecar::list_sessions_blocking("cosmobiologia-observer")
})
.await;
let _ = this.update(cx, |this, cx| {
@@ -900,7 +900,7 @@ impl Shell {
.get("synastry")
.and_then(|c| c.get("partner_chart_id"))
.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());
manual.or_else(|| self.find_synastry_partner_auto())
}
@@ -920,7 +920,7 @@ impl Shell {
.get("composite")
.and_then(|c| c.get("partner_chart_id"))
.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());
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
/// `$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.
fn export_current_to_svg(&self) {
let Some(chart) = self.current_chart.as_ref() else {
@@ -1198,7 +1198,7 @@ impl Shell {
}
};
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"))
.unwrap_or_else(|| std::path::PathBuf::from("."));
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");
return;
}
match tahuantinsuyu_engine::compute_transit_chart(natal) {
match cosmobiologia_engine::compute_transit_chart(natal) {
Ok((birth, instant_label)) => {
let label = format!("{} transito · {}", natal.label, instant_label);
self.insert_derived_free_chart(natal.clone(), birth, label, cx);
@@ -1368,7 +1368,7 @@ impl Shell {
return;
}
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)) => {
let label = format!(
"{} prog-{:.0}a · {}",
@@ -1434,7 +1434,7 @@ impl Shell {
// Pedimos al engine la fecha exacta del retorno. La engine
// expone `compute_planetary_return_chart` que devuelve un
// `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,
) {
Ok((birth, instant_label)) => {
@@ -1460,15 +1460,15 @@ impl Shell {
// 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.
/// 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
/// quedó vacío después del parse — el tree cae al atlas hardcoded.
fn load_city_atlas_from_xdg() -> Option<Vec<tahuantinsuyu_tree::CityPreset>> {
let path = directories::ProjectDirs::from("net", "gioser", "tahuantinsuyu")
fn load_city_atlas_from_xdg() -> Option<Vec<cosmobiologia_tree::CityPreset>> {
let path = directories::ProjectDirs::from("net", "gioser", "cosmobiologia")
.map(|d| d.data_dir().join("atlas.tsv"))?;
if !path.exists() {
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:
/// `"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);
match &birth.birthplace_label {
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.
/// 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.
fn current_age_years(birth: &tahuantinsuyu_model::StoredBirthData) -> f64 {
fn current_age_years(birth: &cosmobiologia_model::StoredBirthData) -> f64 {
use std::time::{SystemTime, UNIX_EPOCH};
let now_secs = SystemTime::now()
.duration_since(UNIX_EPOCH)