feat(nakui-ui): migrar consumer al brazo brahman_cards::load_cards_from_dir

Primera consumer migration del brazo. nakui-ui ya no llama a
nakui_ui_schema::load_modules_from_dir directamente; pasa por
brahman_cards::load_cards_from_dir y extrae UiModule del CardBody.

Beneficios concretos:
- Soporta .ncl además de .json (templates Nickel + merge funcionan
  en cualquier subdir de modules).
- Cards de otros body kinds (Ente/Monad) se skipean limpio con
  toast informativo, no rompen la carga.

Cambios en brahman-cards:
- Nuevo load_cards_from_dir(dir) + variante con readers/filenames
  custom. DEFAULT_CARD_FILENAMES = [card.ncl, card.json, module.ncl,
  module.json] (orden de prioridad).
- 4 tests nuevos del helper.

Cambios en nakui-ui:
- Nueva dep brahman-cards.
- Helper load_ui_modules(dir) -> (Vec<Module>, Vec<String>) envuelve
  el brazo, filtra a UiModule, aplica Module::validate(), detecta
  duplicate ids.
- MetaUi::new usa el helper, emite toast con cards skipped si las hay.
- 3 tests e2e nuevos.

26/26 brahman-cards verdes (+4). 48/48 nakui-ui verdes (+3).
Workspace build verde.

nakui_ui_schema::load_modules_from_dir queda intacto (sus tests lo
usan + otros consumers futuros pueden preferirlo). Migración opt-in.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-05-09 23:32:47 +00:00
parent 2a4443790c
commit f6361bbdca
6 changed files with 449 additions and 10 deletions
+68
View File
@@ -6,6 +6,74 @@ ratio/diff ver `git show <sha>`.
## 2026-05-09
### feat(nakui-ui): migrar consumer al brazo unificado `brahman_cards::load_cards_from_dir`
Primera consumer migration del brazo. `nakui-ui` ya no llama a
`nakui_ui_schema::load_modules_from_dir` directamente — pasa por
`brahman_cards::load_cards_from_dir` y extrae el variant `UiModule`
del `CardBody` de cada Card. Beneficios concretos:
- **Soporta `.ncl` además de `.json`**: el usuario puede dropear un
`card.ncl` (con templates Nickel + merge) en cualquier subdir y
el runtime lo levanta automáticamente. El layout legacy
`examples/nakui-modules/<id>/module.json` sigue funcionando vía
los filenames default `[card.ncl, card.json, module.ncl, module.json]`.
- **Cards de otros body kinds (Ente/Monad) se skipean limpio**:
si el dir contiene Cards no-UiModule, se reportan en un toast
informativo en lugar de fallar la carga.
Cambios en `brahman-cards`:
- **Nuevo `load_cards_from_dir(dir)`** + variante con readers/filenames
custom. Walkea subdirs (orden lexicográfico), busca el primero de
`DEFAULT_CARD_FILENAMES`, dispatcha al reader. Subdirs sin ningún
filename matching se skipean silenciosamente (permite assets/fixtures
sueltos al lado de los cards). Errores per-file se propagan loud
(sin ocultar corrupción).
- **`pub const DEFAULT_CARD_FILENAMES`**: lista canónica probada en
orden. `card.ncl` tiene prioridad sobre `card.json` y sobre los
legacy `module.*`.
- **4 tests nuevos del helper**: walk + skip de subdirs sin
card, prioridad ncl > json, propagación loud de errores per-file,
custom filenames.
Cambios en `nakui-ui`:
- **Nueva dep** `brahman-cards` en `Cargo.toml`.
- **Nuevo helper `load_ui_modules(dir) -> (Vec<Module>, Vec<String>)`**
que envuelve `brahman_cards::load_cards_from_dir`, filtra a
UiModule body, valida cada Module con su `validate()`, ordena
por id, y detecta duplicados. El callsite en `MetaUi::new` pasa
a usarlo y al ver Cards skipped emite un toast informativo.
- **3 tests nuevos**:
- `load_ui_modules_via_brahman_cards_returns_ui_modules_and_skips_others`
— verifica que un dir con UiModule + Ente carga el primero y
reporta el segundo en `skipped`.
- `load_ui_modules_via_brahman_cards_rejects_invalid_module`
`Module::validate()` se sigue aplicando (menu apuntando a view
inexistente rebota).
- `load_ui_modules_detects_duplicate_id` — dos UiModule con
mismo id rebotan con mensaje claro.
Tests totales:
- `brahman-cards`: 22 → 26 (+4 helper directorio).
- `nakui-ui`: 45 → 48 (+3 e2e migración).
- Workspace build verde.
Lo que NO cambió:
- `nakui_ui_schema::load_modules_from_dir` se mantiene intacto (sus
propios tests lo siguen usando, y otros consumers futuros podrían
preferir su error-typing más específico). La migración es opt-in:
`nakui-ui` usa el brazo, ui-schema sigue siendo una API válida.
- Layout actual de `examples/nakui-modules/<id>/module.json` no
requiere cambio. Un usuario puede convertir cualquier módulo a
`card.ncl` sin tocar el dir layout.
**Pendientes para próximos commits** (orden):
1. **Yahweh refactor**: lift del MetaUi runtime a
`crates/modules/ui_engine/` para reuso. El brazo + canónico ya
estables, ahora puede extraerse el meta-form widget genérico.
2. **KCL → Nickel**: kcl_wrapper reemplazado por Nickel contracts;
los 3 schemas .k de nakui modules pasan a .ncl.
3. **card.k eliminado** (es REFERENCE ONLY documentado).
### feat(brahman-cards): Nickel reader + templates con merge nativo (V2)
Sigue al V1 (readers JSON). Ahora el brazo acepta inputs `.ncl`:
los evalúa via `nickel-lang` 2.0, exporta a JSON, y dispatcha por