Files
brahman/crates/apps
sergio 72da2934e8 feat(tahuantinsuyu): "Cartas libres" como sección + guardar a contacto (fase A)
Estructura de cartas no-persistidas con CRUD básico en la UI.

Modelo:
- `FreeChartId(String)` con sentinela `sky_now()` reservado para la
  carta del cielo. Otros ids se generan al vuelo como `free-N`.
- `TreeSelection::FreeChart(FreeChartId)` y `FreeChartsRoot`
  reemplazan al variante puntual `PresentSky` (que era un caso
  especial paralelo).

Tree:
- Sección **"🜨 Cartas libres"** branch fijo al FONDO del tree
  (al contrario de "◇ General" que va arriba). Contiene "Cielo
  ahora" como primera leaf + cualquier carta libre creada.
  Expandida por default.
- Menu contextual:
  * sobre la sección: "Nueva carta libre" → `NewFreeChartRequested`
  * sobre una carta libre: "Guardar como…" + "Borrar" (`sky-now`
    no admite borrar)
- Setter `set_free_charts(Vec<FreeChartEntry>)` actualizado por
  el shell tras cada mutación.

Shell:
- Nuevo state: `free_charts: HashMap<FreeChartId, Chart>` +
  `next_free_id: u32`.
- `ensure_sky_now` inserta/refresca "Cielo ahora" contra el
  reloj actual. Al boot se llama y la carta queda seleccionada.
- `push_free_charts_to_tree` publica la lista al tree
  (sky-now primero, después los `free-N` ordenados).
- Handlers de los 3 nuevos eventos:
  * `NewFreeChartRequested` → crea entry, selecciona
  * `SaveFreeChartRequested(id)` → `save_free_chart_quick`
    (MVP: crea contacto nuevo con el label de la carta + carta
    bajo él; la fase B reemplaza por modal con dropdown)
  * `DeleteFreeChartRequested(id)` → quita de free_charts;
    si era la activa, vuelve al Cielo

10 tests verdes (sin cambios — la lógica nueva afecta paths que
no están cubiertos en los smoke tests actuales).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 21:11:36 +00:00
..
2026-05-10 21:58:16 +00:00
2026-05-10 21:58:16 +00:00