tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 660Markdown 302TOML 157RON 312382 Sutichaykuna

⎇ main Cargo.toml TOML · 872 siq'ikuna · 39.9 KB Ñawpa willay ch'uya

chore: refresco desde el monorepo — 132 miembros, 79 widgets, la galería vuelve y licencia dual d8edd9a9c · Sergio ·

1# Cargo.toml raíz STANDALONE de Llimphi — repo público (GitHub + Gitea).
2# GENERADO por scripts/actualizar-standalone.py --llimphi desde el monorepo:
3# el árbol 02_ruway/llimphi/* se aplana y `shared/{app-bus,foreign-vox}` se
4# vendoriza. `exclude` = crates acoplados al resto del workspace madre.
5[workspace]
6resolver = "2"
7
8# ============================================================
9# Cuadrantes — agregar a medida que se migran
10# ============================================================
11members = [
12    "llimphi",
13    "llimphi-3d",
14    "llimphi-anim",
15    "llimphi-anim-studio",
16    "llimphi-cable",
17    "llimphi-compositor",
18    "llimphi-cpu",
19    "llimphi-despacho",
20    "llimphi-dormir",
21    "llimphi-entrada",
22    "llimphi-gallery",
23    "llimphi-glifos",
24    "llimphi-gpu-bench",
25    "llimphi-hal",
26    "llimphi-hybrid",
27    "llimphi-icons",
28    "llimphi-image",
29    "llimphi-layer",
30    "llimphi-layout",
31    "llimphi-lottie",
32    "llimphi-mesh",
33    "llimphi-motion",
34    "llimphi-raster",
35    "llimphi-reproductor",
36    "llimphi-surface",
37    "llimphi-svg",
38    "llimphi-term-graphics",
39    "llimphi-test",
40    "llimphi-text",
41    "llimphi-theme",
42    "llimphi-ui",
43    "llimphi-voxel",
44    "llimphi-voxel-render",
45    "llimphi-wasm-app-sdk",
46    "llimphi-wasm-demo-counter",
47    "llimphi-wasm-demo-form",
48    "llimphi-wasm-wasi",
49    "llimphi-wire-escena",
50    "llimphi-wire-view",
51    "llimphi-workspace",
52    "modules/bookmarks",
53    "modules/command-palette",
54    "modules/diff-viewer",
55    "modules/fif",
56    "modules/file-picker",
57    "modules/mini-map",
58    "modules/selector",
59    "modules/symbol-outline",
60    "shared/app-bus",
61    "shared/foreign-lottie",
62    "shared/foreign-vox",
63    "shared/grafo",
64    "widgets/accordion",
65    "widgets/app-header",
66    "widgets/app-icon",
67    "widgets/avatar",
68    "widgets/badge",
69    "widgets/banner",
70    "widgets/breadcrumb",
71    "widgets/button",
72    "widgets/calendar",
73    "widgets/card",
74    "widgets/carousel",
75    "widgets/chip",
76    "widgets/clipboard",
77    "widgets/color-picker",
78    "widgets/context-menu",
79    "widgets/datetime-picker",
80    "widgets/detail-table",
81    "widgets/dock-rail",
82    "widgets/edit-menu",
83    "widgets/empty",
84    "widgets/fab",
85    "widgets/field",
86    "widgets/fitted-box",
87    "widgets/form",
88    "widgets/fugaces",
89    "widgets/gallery",
90    "widgets/gauge",
91    "widgets/grid",
92    "widgets/help-menu",
93    "widgets/hero",
94    "widgets/lazy-list",
95    "widgets/list",
96    "widgets/menubar",
97    "widgets/modal",
98    "widgets/navigator",
99    "widgets/nodegraph",
100    "widgets/panel",
101    "widgets/panes",
102    "widgets/progress",
103    "widgets/qr",
104    "widgets/rag-sidebar",
105    "widgets/range-slider",
106    "widgets/rating",
107    "widgets/rive-button",
108    "widgets/router",
109    "widgets/scaffold",
110    "widgets/scroll",
111    "widgets/segmented",
112    "widgets/select",
113    "widgets/seven-segment",
114    "widgets/shortcuts-help",
115    "widgets/skeleton",
116    "widgets/slider",
117    "widgets/spinner",
118    "widgets/splash",
119    "widgets/splitter",
120    "widgets/stat-card",
121    "widgets/status-bar",
122    "widgets/stepper",
123    "widgets/switch",
124    "widgets/tablado",
125    "widgets/table",
126    "widgets/tabs",
127    "widgets/terminal",
128    "widgets/text-area",
129    "widgets/text-editor",
130    "widgets/text-editor-core",
131    "widgets/text-editor-lsp",
132    "widgets/text-input",
133    "widgets/theme-switcher",
134    "widgets/tiled",
135    "widgets/timeline",
136    "widgets/toast",
137    "widgets/toolbar",
138    "widgets/tooltip",
139    "widgets/transport",
140    "widgets/tree",
141    "widgets/waveform",
142    "widgets/wawa-mark",
143    "widgets/wrap",
144]
145
146# `wawa/` se excluye del workspace global porque corre en target
147# `x86_64-unknown-none` y `panic = "abort"`, incompatibles con los
148# perfiles globales. Los crates compartidos se referencian por `path`
149# cruzando la frontera.
150# `llimphi-wawa` está EXCLUIDA, no ausente por olvido. Enciende
151# `llimphi-text/cpu`, que es el backend EXCLUYENTE del `vello` que todo el resto
152# del workspace usa por default — y la unificación de features de cargo los
153# junta, disparando el `compile_error!` que llimphi-text tiene justo para
154# delatarlo. Vive en el mismo mundo que el kernel: se compila aparte, con su
155# propio lock. Sus tests se corren así:
156#   cargo test --manifest-path llimphi-wawa/Cargo.toml \
157#     --no-default-features --features std
158#
159# `llimphi-jaula` está excluida por lo MISMO, del otro lado: enciende
160# `llimphi-text/wire`, el tercer backend excluyente (W4). Es la cáscara de una
161# app dentro de la jaula WASM — el gemelo de `llimphi-wawa`—, y que las dos estén
162# afuera del workspace no es una molestia sino el diseño: son dos procesos en dos
163# lados de una frontera, y forzarlos a compartir un lock sería fingir lo
164# contrario. Sus tests:
165#   cargo test --manifest-path llimphi-jaula/Cargo.toml \
166#     --no-default-features --features std
167#
168# `llimphi-hybrid-android` está excluida **por contagio**: consume `llimphi-wawa`
169# y por lo tanto arrastra el mismo `llimphi-text/cpu`. Es la tercera cáscara de
170# la familia —kernel, jaula, teléfono— y cae del mismo lado de la frontera por
171# el mismo motivo. Se compila así:
172#   cargo check --manifest-path \
173#     android/llimphi-hybrid-android/Cargo.toml
174# y se empaca con `android/scripts/build-android.sh`.
175#
176# `ui-hybrid-android` es la CUARTA, y está excluida por la misma frontera vista
177# desde el otro lado: no consume `llimphi-wawa` sino `llimphi-ui` —el runtime de
178# las 23 apps portadas— pero en su perfil `hybrid`, que apaga `vello` y enciende
179# `llimphi-text/cpu`. Como miembro no podría existir: las features de cargo se
180# unifican por build y **207 crates de este workspace declaran `llimphi-ui` con
181# sus defaults**, así que `cargo check --workspace` mezclaría los dos backends y
182# saltaría el `compile_error!` de `llimphi-text`. O sea que el rasterizador NO es
183# una elección de crate: es de build, y por eso el chasis que lo prueba vive
184# afuera. Se compila así:
185#   cargo check --manifest-path \
186#     android/ui-hybrid-android/Cargo.toml \
187#     --target aarch64-linux-android
188#
189# `llimphi-drm` es la QUINTA, y también por contagio: consume `llimphi-wawa`
190# —la cáscara que ya sabía pintar sin GPU— para llevar su salida a un dumb
191# buffer DRM. Nació miembro el 2026-09-28 y **dejó `main` en rojo el mismo día**:
192# `cargo check -p llimphi-drm` solo pasa, porque ahí el único backend en juego es
193# `cpu`; el `--workspace` lo junta con los 207 crates que traen `vello` por
194# default y salta el `compile_error!`. Es exactamente lo que la Regla 5 dice con
195# sus cuatro flags, y la lección de al lado —el rasterizador es de build, no de
196# crate— estaba escrita tres párrafos más arriba. Se compila así:
197#   cargo check --manifest-path llimphi-drm/Cargo.toml --examples
198exclude = [
199    "android",
200    "demo",
201    "llimphi-drm",
202    "llimphi-jaula",
203    "llimphi-jaula/nahual-jailed",
204    "llimphi-registro",
205    "llimphi-showreel",
206    "llimphi-video-plane",
207    "llimphi-voxel-app",
208    "llimphi-voxel-studio",
209    "llimphi-wasm-core",
210    "llimphi-wasm-dist",
211    "llimphi-wasm-net",
212    "llimphi-wasm-open",
213    "llimphi-wasm-registry",
214    "llimphi-wasm-runner",
215    "llimphi-wawa",
216    "modules/allichay",
217    "modules/plugin-host",
218    "modules/shuma-term",
219]
220
221[workspace.package]
222version = "0.1.0"
223edition = "2021"
224rust-version = "1.80"
225license = "MIT OR Apache-2.0"
226authors = ["Sergio <sergio@gioser.net>"]
227publish = true
228repository = "https://git.tawasuyu.net/tawasuyu/llimphi"
229
230[workspace.dependencies]
231# === Configuración declarativa (vocabulario de esquemas) ===
232# Escala única de `nice` de la sesión (compositor · marco · app · segundo plano
233# · lote) + las tres formas de aplicarla (propia / pid vivo / pre_exec).
234# Telemetría local de desarrollo (stderr+panics+tracing → $XDG_STATE_HOME/tawasuyu/<dominio>/<bin>.log)
235# default = [] (núcleo liviano sin vello); `bake` es opt-in. Declaramos
236# default-features = false aquí para que el `default-features = false` de los
237# consumidores (splash/greeter/compositor) se honre y no quede el warning.
238# === Registro de apps / menú global ===
239app-bus = { path = "shared/app-bus", version = "0.1.0" }
240# === Centro de eventos (notificaciones + capturas + clipboard + …) ===
241# El censo de red de la máquina (netstat completo: socket → proceso → unidad) +
242# huella de red + drift de puertos + contabilidad por unidad. Ver `shared/PLAN-RED.md`.
243# La baliza de LAN: el descubridor por multicast, con el payload opaco. Promovido
244# de `uya-app::lan`, que es el de los tres del arbol que resuelve los tres modos
245# de fallo reales. Ver `shared/PLAN-RED.md` §F1.
246# === Puente de drag-and-drop compositor → app (suple winit en Wayland) ===
247# === Serialización ===
248serde = { version = "1", features = ["derive"] }
249serde_json = "1"
250lsp-types = "0.97"
251serde-big-array = "0.5"
252postcard = { version = "1", features = ["use-std"] }
253toml = "0.8"
254ron = "0.8"
255bincode = "1"
256base64 = "0.22"
257
258# === Errores ===
259thiserror = "2"           # bump uniforme; arje (era 1) puede requerir ajustes menores
260anyhow = "1"
261
262# === Async ===
263tokio = { version = "1", features = ["full"] }
264tokio-util = { version = "0.7", features = ["compat"] }
265async-trait = "0.1"
266futures = "0.3"
267
268# === Observabilidad ===
269tracing = "0.1"
270tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
271
272# Sonda de librerías del sistema en build.rs. La usa `auth-huellita` para
273# detectar `libfprint` sin volverla una dependencia dura del workspace.
274pkg-config = "0.3"
275
276# === Linux primitives (arje) ===
277nix = { version = "0.29", features = ["signal", "process", "sched", "mount", "fs", "socket", "net", "user", "reboot"] }
278libc = "0.2"
279# DRM/KMS legacy (dumb buffer) para el splash nativo del arranque sin parpadeo.
280# Misma versión que reexporta smithay (mirada-compositor) — el lock ya la fija.
281drm = "0.14"
282font8x8 = { version = "0.3", default-features = false }
283
284# === IDs / Hash / Crypto ===
285ulid = { version = "1", features = ["serde"] }
286uuid = { version = "1", features = ["v4", "rng-getrandom"] }
287sha2 = "0.10"
288blake3 = "1.5"
289ed25519-dalek = "2"
290aes-gcm = "0.10"
291chacha20 = "0.9"
292chacha20poly1305 = "0.10"
293argon2 = "0.5"
294rand = "0.8"
295# TOTP (RFC 6238) del segundo factor de nakui: HMAC-SHA1 es lo que hablan
296# Google Authenticator, Aegis y los tokens de hardware — no es elección
297# nuestra, es el formato del ecosistema. base32 para el secreto del QR.
298hmac = "0.12"
299sha1 = "0.10"
300data-encoding = "2"
301
302# === WASM (arje) ===
303# wasmi 1.0: unifica la versión con wawa (su kernel ya corre 1.0), para
304# que el ABI WASM del host sea idéntico en Linux y en bare-metal.
305wasmi = "1.0"
306wat = "1"
307# wasmtime 46 (Fase 1 del pipeline JS): tier 0 de puriy-js pasa de wasmi
308# (intérprete) a Wasmtime AOT (Cranelift → nativo) en Linux — quita la doble
309# interpretación de QuickJS.wasm. En wawa bare-metal el runtime es Pulley (spike
310# Q1 cerrado); mismo crate, distinto backend.
311wasmtime = "46"
312
313# === Storage / DB ===
314sled = "0.34"
315rusqlite = { version = "0.31", features = ["bundled", "blob"] }
316
317# === Ingesta de documentos (iniy-ingest: PDF / EPUB) ===
318pdf-extract = "0.7"
319epub = "2.1"
320
321# === Bulk import Wikipedia (iniy-wiki dump) ===
322bzip2 = "0.4"
323
324# === Compresión (minga multi-bundle) ===
325zstd = "0.13"
326xz2 = "0.1"
327# Contenedores adicionales del visor Archive de nahual (sólo listado).
328sevenz-rust = "0.6"
329unrar = "0.5"
330
331# === HTTP server (iniy-server) ===
332axum = "0.7"
333# WebSocket pelado (sin framework HTTP): lo usa `shuma-ide-host`, que sirve el
334# protocolo de integración de IDE de Claude Code en loopback. Ya estaba en el
335# lock por transitividad; acá se declara para poder usarlo directo.
336tokio-tungstenite = "0.24"
337tower = "0.5"
338
339# === ANN sobre embeddings (iniy nli --ann) ===
340instant-distance = "0.6"
341
342# === P2P (minga) ===
343libp2p = { version = "0.56", features = ["tokio", "tcp", "dns", "noise", "yamux", "macros", "kad", "identify", "relay", "dcutr", "autonat", "mdns"] }
344libp2p-stream = "=0.4.0-alpha"
345libp2p-allow-block-list = "0.6"
346
347# === SSH (ssh, sandokan RemoteEngine, matilda) ===
348russh = "0.54"
349
350# === Math determinista cross-platform (dominium) ===
351libm = "0.2"
352
353# === SMF (takiy-midi) ===
354# midly: parser/emitter SMF tipo 0/1, no_std-friendly, sin allocs en hot path.
355midly = "0.5"
356
357# === Code parsing (minga) ===
358# `wayland-data-control` trae el backend wl-clipboard-rs: bajo mirada (Wayland
359# propio, sin Xwayland para apps nativas) arboard-x11 fallaba a no-op silencioso
360# y el clipboard de los text-editor quedaba muerto. Con la feature habla
361# zwlr_data_control_manager_v1 (que mirada expone) y cae a X11 si no hay Wayland.
362arboard = { version = "3", features = ["wayland-data-control"] }
363ropey = "1.6"
364# El runtime lee gramáticas por ABI, y ahí está el acople: 0.24 lee hasta la 14,
365# 0.25 lee 13–15. Se subió el 2026-09-06 porque `tree-sitter-rust` 0.23.3 (ABI 14)
366# lee `&raw` como el arranque de una referencia cruda, así que **una variable
367# llamada `raw` prestada con `&`** rompe el archivo entero para la gramática:
368# 69 de 6.428 archivos de este repo (1,1 %). La 0.24.2 lo arregla, pero es ABI 15
369# y por eso arrastra al runtime. Las otras gramáticas siguen en ABI 14 y cargan
370# igual — 0.25 es compatible hacia atrás.
371tree-sitter = "0.25"
372tree-sitter-rust = "0.24"
373tree-sitter-python = "0.23"
374tree-sitter-typescript = "0.23"
375tree-sitter-javascript = "0.23"
376tree-sitter-go = "0.23"
377# C: el quinto dialecto que minga versiona por AST (el kernel y todo lo ajeno
378# que la suite absorbe está en C).
379tree-sitter-c = "0.23"
380# Dart entra por zorge (SDD-SERVIDOR-AJENO §A.1, RA-2): el otro proyecto es
381# Flutter, y Dart 3 es lo más parecido a Rust que hay del otro lado —tipado
382# estático, `sealed` con `switch` exhaustivo, y `_nombre` privado de verdad—.
383# El fork `orchard` y no `tree-sitter-dart` a secas. El motivo original era el
384# ABI: `tree-sitter-dart` se generó con la 15 y el runtime del workspace leía
385# hasta la 14. Con el runtime en 0.25 ese motivo **ya no aplica**; el fork se
386# conserva porque es lo que está probado, no porque haga falta.
387tree-sitter-dart-orchard = "0.3"
388
389# === FS notify ===
390notify = "6.1"
391
392# === Grafos (iniy, nakui-core ya lo usa directo en 0.6) ===
393petgraph = "0.6"
394
395# === Image decoding (nahual-image-viewer-llimphi) ===
396# default-features = false: nos quedamos con PNG + JPEG + WebP (lossless).
397# tullpu-render exporta a las tres; AVIF/TIFF/… los habilitamos si una app
398# los pide específicamente.
399# Decoders puro-Rust baratos; avif queda fuera (arrastra dav1d/rav1e).
400image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp", "gif", "bmp", "ico", "tiff", "tga", "qoi"] }
401# ONNX Runtime para los proveedores de píxel reales (pixel-verbo-onnx: segmentación
402# u2net/isnet, inpaint, restyle…). `download-binaries` (default) baja el runtime nativo
403# solo; ya lo arrastraba fastembed (rimay-verbo) transitivo — aquí lo declaramos directo.
404ort = "2.0.0-rc.9"
405
406# Rasterizador vectorial CPU (relleno/trazo anti-aliased) para capas vectoriales de tullpu.
407tiny-skia = "0.11"
408# Booleanos de polígonos robustos (union/intersection/difference/xor) para el
409# clipper vectorial de tullpu — restar/intersecar paths que se solapan
410# parcialmente, que la regla de relleno no expresa. Ya estaba en el lock.
411geo = "0.28"
412
413# === FUSE (minga-vfs) ===
414# default-features = false: prescinde de pkg-config/libfuse-dev en build.
415# ⚠ El montaje pasa a ser Rust puro, y el helper `fusermount3` es el RESPALDO, no el camino: leído en
416# `fuser-0.15.1/src/mnt/fuse_pure.rs`, `fuse_mount_pure` intenta primero `fuse_mount_sys` —el
417# `mount(2)` directo sobre `/dev/fuse`, que anda como root sin ningún helper— y sólo cae a
418# `fusermount3` si eso no se permite; desmontar hace `umount2(MNT_DETACH)` con la misma lógica. La
419# excepción es `MountOption::AutoUnmount`, que fuerza el helper SIEMPRE.
420# Importa para una distro: como root y sin AutoUnmount, la imagen NO necesita empaquetar `fuse3`.
421fuser = { version = "0.15", default-features = false }
422
423# === CLI / auth (minga) ===
424clap = { version = "4", features = ["derive"] }
425rpassword = "7"
426
427# === PAM (auth-core) ===
428pam = "0.8"
429# El FFI crudo de PAM. `pam` 0.8 lo envuelve, pero sus enums están calcados de
430# Linux-PAM; fuera de Linux (OpenPAM) se usa esto directo, porque genera sus
431# bindings con bindgen contra los encabezados de la máquina. Ver
432# `shared/auth/auth-core/src/login_session_bsd.rs`.
433pam-sys = "1.0.0-alpha5"
434
435# === D-Bus (arje compat) ===
436zbus = { version = "4", default-features = false, features = ["tokio"] }
437
438# === Tests ===
439tempfile = "3"
440
441# === Llimphi (motor gráfico soberano) ===
442# wgpu sobre Vulkan/Metal/DX12, winit para ventana en dev Linux.
443# raw-window-handle 0.6 alinea winit 0.30 con wgpu 29.
444# vello 0.9 = rasterizador vectorial sobre wgpu 29 (renderer GPU "wgpu" + opt-in "hybrid" CPU+GPU).
445#
446# **El 27→29 no fue por gusto** (2026-07-28): `vello_hybrid 0.0.9` —el ÚNICO
447# rasterizador que el driver Mali del teléfono digiere, ver
448# `02_ruway/llimphi/android/DIAGNOSTICO.md`— vive en wgpu 29, y dos versiones de
449# wgpu no comparten un `Device`. La migración salió barata porque `vello 0.9`
450# usa el mismo peniko 0.6.1 y no movió su API de `Scene`: el bump de vello dio
451# CERO errores; todos los que hubo fueron deriva de wgpu, y concentrada en los
452# cuatro crates que tienen código wgpu propio.
453# taffy 0.12 = motor Flexbox/Grid puro Rust (0.9→0.12 en 2026-07-27: arregla el percent de ítem de grid en track sizing).
454# parley 0.6 = shaping/layout de texto compatible con peniko 0.6 (que vello 0.7 expone).
455wgpu = "29"
456# El compilador de shaders que wgpu lleva adentro. Se declara acá para que los
457# tests que validan WGSL headless (llimphi-3d, supay-render-llimphi) usen la
458# MISMA versión que después compila esos shaders en la GPU. Con dos versiones,
459# un test puede dar verde sobre un shader que el runtime rechaza — o al revés.
460naga = "29"
461winit = "0.30"
462raw-window-handle = "0.6"
463pollster = "0.4"
464# `default-features = false` acá arriba y no en cada consumidor: el default de
465# vello es ["wgpu","wgpu_default"], y `llimphi-text`/`llimphi-compositor` sólo
466# quieren sus TIPOS (Scene, peniko), no el motor de GPU. Declararlo abajo no
467# alcanza — cargo IGNORA `default-features` en un dep heredado si la raíz no lo
468# fijó, y lo avisa con un warning fácil de pasar por alto. Quien necesita el
469# motor lo pide por feature (ver llimphi-raster).
470vello = { version = "0.9", default-features = false }
471# Renderer hybrid CPU+GPU sin compute shaders (mejor compat WebGL2/Adreno viejas).
472# Opt-in; el renderer "wgpu" sigue siendo el default.
473vello_hybrid = "0.0.9"
474# foreign-lottie = fork vendorizado de velato 0.9 (Lottie → vello::Scene),
475# completado para no paniquear ante features no soportadas. Lo consume
476# llimphi-lottie. Ver shared/foreign-lottie.
477foreign-lottie = { path = "shared/foreign-lottie", version = "0.1.0" }
478# Árbol de accesibilidad para lectores de pantalla (NVDA/VoiceOver/Orca/TalkBack).
479# Lo consume el runtime de Llimphi (iter 2/3 del plan AccessKit); el modelo
480# `SemanticsSpec` del compositor es independiente de estas crates.
481accesskit = "0.24"
482accesskit_winit = "0.33"
483taffy = "0.12"
484# parley = shaping completo (bidi, ligatures, fallback CJK/emoji vía fontique, line break).
485parley = "0.6"
486# Bucle Elm (input→update→view→layout→raster→present). Lo consumen las apps.
487# `config-wawa`: el sentido de la rueda (ratón / touchpad, por separado) sale
488# del bus `wawa-config` y se fija al arrancar cada app, con watcher para el
489# cambio en caliente. Va acá y no app por app a propósito: es una preferencia
490# del HUMANO, no de cada app, y ninguna app del monorepo debería poder
491# desobedecerla por olvido. Ver `llimphi-ui/src/rueda.rs`.
492llimphi-ui = { path = "llimphi-ui", version = "0.1.0" }
493# El compositor DIRECTO, para que el catálogo de widgets cuelgue de él y no del
494# shell de escritorio (W4.6). Un widget que dependa de `llimphi-ui` arrastra
495# winit + accesskit + arboard + vello, y con eso queda fuera del alcance de una
496# app enjaulada; colgando de acá sirve igual en Linux, en el kernel y en la jaula.
497#
498# `default-features = false` VA ACÁ Y NO EN CADA WIDGET. Es la trampa recurrente
499# de cargo: apagar los defaults desde un miembro NO HACE NADA si el workspace
500# declaró la dep sin ellos (cargo lo avisa y lo ignora). Ya pasó con taffy, vello
501# y peniko. Sin esto, cada widget encendería el backend `vello` del compositor y
502# volvería a quedar fuera del alcance de una app enjaulada — que es justamente lo
503# que W4.6 vino a arreglar. Quien ensambla la app elige el backend: `llimphi-ui`
504# en Linux, `llimphi-jaula` en la jaula, `llimphi-wawa` en el kernel.
505llimphi-compositor = { path = "llimphi-compositor", version = "0.1.0" }
506# Tier 3 — apps WASM con UI Llimphi real. El guest pinta un WireNode (IR
507# serializable), el host (runner) lo materializa en View<Msg> y rebota los
508# eventos al update del guest. SDK = lado guest, runner = lado host.
509llimphi-wire-view = { path = "llimphi-wire-view", version = "0.1.0" }
510llimphi-wire-escena = { path = "llimphi-wire-escena", version = "0.1.0" }
511llimphi-wasm-app-sdk = { path = "llimphi-wasm-app-sdk", version = "0.1.0" }
512# Núcleo puro de distribución (CAS + verificación + resolve), SIN runner/GPU.
513# Cara con baterías: re-exporta core + puente al runner para correr la app.
514llimphi-wasm-wasi = { path = "llimphi-wasm-wasi", version = "0.1.0" }
515# Transporte P2P del bytecode por hash sobre BrahmanNet (card-net).
516llimphi-3d = { path = "llimphi-3d", version = "0.1.0" }
517# Runner wlr-layer-shell: corre un `App` de Llimphi como barra anclada a un
518# borde (no como ventana), reusando la plumbing sctk+wgpu que pata probó.
519llimphi-layer = { path = "llimphi-layer", version = "0.1.0" }
520# Paleta semántica compartida por las apps y los widgets.
521llimphi-theme = { path = "llimphi-theme", version = "0.1.0" }
522# Tweens y helpers de animación sobre el bucle Elm.
523llimphi-motion = { path = "llimphi-motion", version = "0.1.0" }
524# Máquina de estados de animación (estilo Rive) clip-agnóstica. Núcleo puro;
525# el render lo cablea el consumidor (llimphi-lottie). Escalón sobre el playback.
526llimphi-anim = { path = "llimphi-anim", version = "0.1.0" }
527llimphi-dormir = { path = "llimphi-dormir", version = "0.1.0" }
528# Studio de animación «rive»: además del editor (bin), expone como lib los
529# documentos serializables (Doc + RigDoc + Project) que carga mirada-fondo.
530llimphi-anim-studio = { path = "llimphi-anim-studio", version = "0.1.0" }
531# Render de mallas deformables (skel::Mesh) a vello Scene: vectorial y texturizada.
532llimphi-mesh = { path = "llimphi-mesh", version = "0.1.0" }
533# Iconos vectoriales (BezPath en grid 24×24) compartidos por todas las apps.
534llimphi-icons = { path = "llimphi-icons", version = "0.1.0" }
535# Puente fino vello_svg → Llimphi para SVG arbitrario (íconos .desktop, logos).
536llimphi-svg = { path = "llimphi-svg", version = "0.1.0" }
537# Puente fino velato (Lottie) → Llimphi para animación vectorial autorada (.json).
538llimphi-lottie = { path = "llimphi-lottie", version = "0.1.0" }
539llimphi-image = { path = "llimphi-image", version = "0.1.0" }
540# Decodificador de protocolos de gráficos de terminal (kitty/sixel) → RGBA.
541llimphi-term-graphics = { path = "llimphi-term-graphics", version = "0.1.0" }
542# Widgets reusables sobre llimphi-ui — uno por crate.
543llimphi-widget-app-header = { path = "widgets/app-header", version = "0.1.0" }
544llimphi-widget-banner = { path = "widgets/banner", version = "0.1.0" }
545llimphi-widget-button = { path = "widgets/button", version = "0.1.0" }
546llimphi-widget-rive-button = { path = "widgets/rive-button", version = "0.1.0" }
547llimphi-widget-card = { path = "widgets/card", version = "0.1.0" }
548llimphi-clipboard = { path = "widgets/clipboard", version = "0.1.0" }
549llimphi-widget-context-menu = { path = "widgets/context-menu", version = "0.1.0" }
550llimphi-widget-edit-menu = { path = "widgets/edit-menu", version = "0.1.0" }
551llimphi-widget-menubar = { path = "widgets/menubar", version = "0.1.0" }
552llimphi-widget-list = { path = "widgets/list", version = "0.1.0" }
553llimphi-widget-grid = { path = "widgets/grid", version = "0.1.0" }
554llimphi-widget-table = { path = "widgets/table", version = "0.1.0" }
555llimphi-widget-color-picker = { path = "widgets/color-picker", version = "0.1.0" }
556llimphi-widget-slider = { path = "widgets/slider", version = "0.1.0" }
557llimphi-widget-app-icon = { path = "widgets/app-icon", version = "0.1.0" }
558llimphi-widget-scroll = { path = "widgets/scroll", version = "0.1.0" }
559llimphi-widget-lazy-list = { path = "widgets/lazy-list", version = "0.1.0" }
560llimphi-widget-splitter = { path = "widgets/splitter", version = "0.1.0" }
561llimphi-widget-stat-card = { path = "widgets/stat-card", version = "0.1.0" }
562llimphi-widget-tabs = { path = "widgets/tabs", version = "0.1.0" }
563llimphi-module-command-palette = { path = "modules/command-palette", version = "0.1.0" }
564llimphi-module-diff-viewer = { path = "modules/diff-viewer", version = "0.1.0" }
565llimphi-module-fif = { path = "modules/fif", version = "0.1.0" }
566llimphi-module-file-picker = { path = "modules/file-picker", version = "0.1.0" }
567llimphi-module-bookmarks = { path = "modules/bookmarks", version = "0.1.0" }
568llimphi-module-mini-map = { path = "modules/mini-map", version = "0.1.0" }
569llimphi-module-symbol-outline = { path = "modules/symbol-outline", version = "0.1.0" }
570llimphi-widget-theme-switcher = { path = "widgets/theme-switcher", version = "0.1.0" }
571llimphi-widget-text-area = { path = "widgets/text-area", version = "0.1.0" }
572llimphi-widget-text-editor-core = { path = "widgets/text-editor-core", version = "0.1.0" }
573llimphi-widget-text-editor = { path = "widgets/text-editor", version = "0.1.0" }
574llimphi-widget-text-editor-lsp = { path = "widgets/text-editor-lsp", version = "0.1.0" }
575llimphi-widget-text-input = { path = "widgets/text-input", version = "0.1.0" }
576llimphi-widget-tiled = { path = "widgets/tiled", version = "0.1.0" }
577llimphi-widget-nodegraph = { path = "widgets/nodegraph", version = "0.1.0" }
578llimphi-widget-tree = { path = "widgets/tree", version = "0.1.0" }
579grafo-nav = { path = "shared/grafo", version = "0.1.0" }
580# La lengua de expresiones compartida (PLAN-CRUCES §A5). `default-features =
581# false` acá NO: los consumidores Linux (maskay, pizarra, yupay, krama) la
582# quieren con `std`; el kernel y las jaulas la piden sin default desde su propio
583# manifiesto, como hacen con `format` y `dataflow`.
584llimphi-widget-navigator = { path = "widgets/navigator", version = "0.1.0" }
585llimphi-widget-detail-table = { path = "widgets/detail-table", version = "0.1.0" }
586llimphi-widget-select = { path = "widgets/select", version = "0.1.0" }
587# `gpu` explícito: el camino GPU-directo del modo grilla pasó a ser una feature
588# (para que el terminal pueda salir del proceso), y este `default-features =
589# false` la apagaba para TODOS los que lo toman por el workspace — dejando a
590# `shuma-module-shell` sin `CellPipeline`. Pedirla acá devuelve exactamente el
591# comportamiento de antes; quien la quiera apagar lo hace en su manifiesto.
592llimphi-widget-terminal = { path = "widgets/terminal", version = "0.1.0" }
593# Sello vectorial wawa (rombo + W implícita + Merkle Core).
594llimphi-widget-wawa-mark = { path = "widgets/wawa-mark", version = "0.1.0" }
595# Widgets de elegancia transversal (tooltip, spinner, progress, toast,
596# modal, empty, status-bar, shortcuts-help, splash).
597llimphi-widget-tooltip = { path = "widgets/tooltip", version = "0.1.0" }
598llimphi-widget-spinner = { path = "widgets/spinner", version = "0.1.0" }
599llimphi-widget-progress = { path = "widgets/progress", version = "0.1.0" }
600llimphi-widget-toast = { path = "widgets/toast", version = "0.1.0" }
601llimphi-widget-modal = { path = "widgets/modal", version = "0.1.0" }
602llimphi-widget-empty = { path = "widgets/empty", version = "0.1.0" }
603llimphi-widget-status-bar = { path = "widgets/status-bar", version = "0.1.0" }
604llimphi-widget-shortcuts-help = { path = "widgets/shortcuts-help", version = "0.1.0" }
605llimphi-widget-help-menu = { path = "widgets/help-menu", version = "0.1.0" }
606llimphi-widget-timeline = { path = "widgets/timeline", version = "0.1.0" }
607llimphi-widget-transport = { path = "widgets/transport", version = "0.1.0" }
608llimphi-widget-waveform = { path = "widgets/waveform", version = "0.1.0" }
609llimphi-widget-splash = { path = "widgets/splash", version = "0.1.0" }
610# Controles de formulario y signaling (switch, segmented, breadcrumb,
611# badge, avatar, skeleton, field).
612llimphi-widget-switch = { path = "widgets/switch", version = "0.1.0" }
613llimphi-widget-segmented = { path = "widgets/segmented", version = "0.1.0" }
614llimphi-widget-rag-sidebar = { path = "widgets/rag-sidebar", version = "0.1.0" }
615llimphi-widget-dock-rail = { path = "widgets/dock-rail", version = "0.1.0" }
616llimphi-widget-toolbar = { path = "widgets/toolbar", version = "0.1.0" }
617llimphi-widget-breadcrumb = { path = "widgets/breadcrumb", version = "0.1.0" }
618llimphi-widget-badge = { path = "widgets/badge", version = "0.1.0" }
619llimphi-widget-avatar = { path = "widgets/avatar", version = "0.1.0" }
620llimphi-widget-skeleton = { path = "widgets/skeleton", version = "0.1.0" }
621llimphi-widget-field = { path = "widgets/field", version = "0.1.0" }
622# Firma visual transversal (gradient sutil + hairline accent).
623# `default-features = false` acá y no en `card`: los defaults de un widget sólo
624# se pueden apagar desde la declaración del WORKSPACE (la trampa recurrente de
625# cargo). Sin esto, `card` arrastraría a `panel` con backend `vello` y volvería a
626# quedar fuera de una jaula, aunque `card` pidiera `wire`.
627llimphi-widget-panel = { path = "widgets/panel", version = "0.1.0" }
628llimphi-widget-panes = { path = "widgets/panes", version = "0.1.0" }
629# Widgets Flutter-like — composición sobre primitivas Tier 1/3 ya
630# expuestas (sombra, gradient, animated, ripple).
631llimphi-widget-chip = { path = "widgets/chip", version = "0.1.0" }
632llimphi-widget-fab = { path = "widgets/fab", version = "0.1.0" }
633llimphi-widget-fugaces = { path = "widgets/fugaces", version = "0.1.0" }
634llimphi-widget-wrap = { path = "widgets/wrap", version = "0.1.0" }
635llimphi-widget-range-slider = { path = "widgets/range-slider", version = "0.1.0" }
636llimphi-widget-calendar = { path = "widgets/calendar", version = "0.1.0" }
637llimphi-widget-datetime-picker = { path = "widgets/datetime-picker", version = "0.1.0" }
638llimphi-widget-form = { path = "widgets/form", version = "0.1.0" }
639llimphi-widget-accordion = { path = "widgets/accordion", version = "0.1.0" }
640llimphi-widget-stepper = { path = "widgets/stepper", version = "0.1.0" }
641llimphi-widget-fitted-box = { path = "widgets/fitted-box", version = "0.1.0" }
642llimphi-widget-carousel = { path = "widgets/carousel", version = "0.1.0" }
643llimphi-widget-rating = { path = "widgets/rating", version = "0.1.0" }
644llimphi-widget-gauge = { path = "widgets/gauge", version = "0.1.0" }
645llimphi-widget-seven-segment = { path = "widgets/seven-segment", version = "0.1.0" }
646llimphi-widget-scaffold = { path = "widgets/scaffold", version = "0.1.0" }
647llimphi-widget-hero = { path = "widgets/hero", version = "0.1.0" }
648llimphi-widget-router = { path = "widgets/router", version = "0.1.0" }
649llimphi-workspace = { path = "llimphi-workspace", version = "0.1.0" }
650# Abstracción Selector — host (paths) + wawa (khipus).
651llimphi-module-selector = { path = "modules/selector", version = "0.1.0" }
652
653# === Filesystem helpers ===
654directories = "5"
655
656# === Diff line-based (llimphi-module-diff-viewer) ===
657# `similar` es la crate de facto: implementa Myers + Patience + LCS,
658# expone `TextDiff` con ChangeTag por línea (Equal/Insert/Delete),
659# zero deps fuera de std. La 2.x es estable hace años.
660similar = "2"
661
662# === Fuzzy matching (shuma-history) ===
663# nucleo-matcher = mismo matcher que helix-editor: rápido, Unicode-correct,
664# bonus por prefijos, ranking estable. La versión 0.3 expone el API simple
665# que necesitamos (Matcher + Pattern + score).
666nucleo-matcher = "0.3"
667
668# === Transporte autenticado (shuma-link) ===
669# snow = framework Noise pure-rust. Lo usamos en modo Noise_XK (cliente
670# conoce la pubkey del servidor, server descubre la del cliente y la
671# valida contra una allowlist). ChaCha20-Poly1305 + X25519 + BLAKE2s.
672# La versión 0.9 viene pinneada por libp2p, así nos alineamos.
673snow = "0.9"
674hex = "0.4"
675
676# === PTY + emulador de terminal (shuma-exec, módulos REPL) ===
677# portable-pty aloja un PTY cross-platform; lo usamos para los
678# comandos TUI tipo vim/htop/less que necesitan un terminal de verdad.
679# vt100 parsea la secuencia de bytes que el PTY emite (ANSI + cursor
680# movement + erase + screen state) y mantiene un buffer de pantalla
681# renderizable como grid.
682portable-pty = "0.9"
683vt100 = "0.16"
684
685# === WASM web (tawasuyu) ===
686wasm-bindgen = "0.2"
687wasm-bindgen-futures = "0.4"
688js-sys = "0.3"
689web-sys = "0.3"
690glam = "0.30"
691
692# === Markdown (pluma) ===
693pulldown-cmark = { version = "0.12", default-features = false, features = ["html"] }
694
695# === Archivos comprimidos (nahual archive viewer) ===
696# Sólo listamos el directorio central (nombres/tamaños); no descomprimimos,
697# por eso default-features=false alcanza para ZIP. Para tar.gz sí
698# descomprimimos en streaming con flate2 (ya declarado arriba), saltando
699# los datos de cada entrada — sólo leemos headers.
700zip = { version = "2.4", default-features = false }
701tar = { version = "0.4", default-features = false }
702
703# === Fuentes (nahual font viewer) ===
704# Parseo de TTF/OTF/TTC y extracción de contornos de glifo a paths.
705ttf-parser = "0.25"
706
707# ============================================================
708# Intra-workspace deps de nahual (referenciadas por workspace = true)
709# ============================================================
710
711# ============================================================
712# Intra-workspace deps de pineal (módulo de gráficos)
713# ============================================================
714
715# ============================================================
716# Intra-workspace deps de iniy (laboratorio semántico de creencias)
717# ============================================================
718# la física de decaimiento de khipu la importa iniy-derive (SDD iniy §3)
719
720# === auto: declarados por crates internos faltantes ===
721
722# === auto: externas de eternal ===
723celestial-eop-data = { version = "0.1"}
724approx = "0.5"
725byteorder = "1.5"
726cc = "1.0"
727chrono = "0.4"
728chrono-tz = "0.10"
729crc32fast = "1.4"
730criterion = "0.5"
731csv = "1.4"
732flate2 = "1.0"
733glob = "0.3"
734indicatif = "0.18"
735lz4_flex = "0.11"
736memmap2 = "0.9"
737# Cliente Wayland (lado cliente) — lo usa hapiy para hablar zwlr_screencopy
738# contra mirada (u otro compositor wlroots) y capturar la pantalla.
739wayland-client = "0.31"
740wayland-protocols-wlr = { version = "0.3", features = ["client"] }
741wayland-protocols-misc = { version = "0.3", features = ["client"] }
742# PipeWire (bindings a libpipewire-0.3, MIT) — el transporte de video que
743# `xdg-desktop-portal` exige para compartir pantalla. Lo usa
744# `mirada-screencast`; no entra al compositor (ver su LEEME: el productor es
745# un cliente wlr-screencopy, no el compositor mismo).
746#
747# `v0_3_34` es el piso que habilita `pw_stream_trigger_process` — sin él un
748# nodo DRIVER no se puede disparar y el consumidor recibe CERO cuadros, sin
749# error. Se pide el mínimo que hace falta, no la última: la feature declara
750# contra qué libpipewire se compila, y pedir de más rompería en una distro con
751# la biblioteca más vieja.
752pipewire = { version = "0.10", features = ["v0_3_34"] }
753libspa = "0.10"
754mockito = "1.0"
755ndarray = "0.15"
756num-traits = "0.2"
757once_cell = "1.19"
758parking_lot = "0.12"
759png = "0.18"
760proptest = "1.4"
761quick-xml = "0.31"
762rayon = "1.8"
763regex = "1.11"
764# TLS por **rustls**, no por el `default-tls` de reqwest (que es `native-tls`
765# y arrastra `openssl-sys`). Dos razones, y la segunda es la que muerde:
766#  1. `openssl-sys` NO cross-compila a `aarch64-linux-android` — su build
767#     script no encuentra la libreria del NDK. Con el default puesto, toda
768#     app que toque HTTP queda fuera del porte a Android (khipu fue la
769#     primera en chocar).
770#  2. Seis de los doce consumidores YA pedian `rustls-tls` a mano. Como las
771#     features de cargo son aditivas, eso no apagaba `default-tls`: estaban
772#     linkeando **las dos** pilas de TLS creyendo que usaban una. Esto hace
773#     verdadero lo que esos crates ya decian.
774# El resto de los defaults de reqwest se conservan uno por uno.
775# ⚠️ Cambio de comportamiento a nombrar: rustls valida contra las raices
776# empaquetadas (webpki-roots), no contra el almacen de certificados del SO.
777# Para las APIs publicas que consume la suite da igual; un servidor con CA
778# propia habria que agregarlo explicitamente.
779reqwest = { version = "0.12", default-features = false, features = [
780    "rustls-tls",
781    "charset",
782    "http2",
783    "macos-system-configuration",
784] }
785tiff = "0.11"
786wide = "0.7"
787wiremock = "0.6"
788
789# === i18n (rimay-localize) ===
790fluent-bundle = "0.15"
791unic-langid = { version = "0.9", features = ["macros"] }
792sys-locale = "0.3"
793
794# === Servo (puriy-engine) ===
795# Crates publicados de Servo embebibles individualmente. html5ever/markup5ever
796# ya entran via ammonia→surrealdb→nakui, así que alineamos versión para no
797# duplicar el árbol. markup5ever_rcdom es el DOM Rc-based simple (suficiente
798# para Fase 2: parsear y renderizar, sin scripting). cssparser es el tokenizer
799# CSS de Stylo, sirve para inline styles. ureq = HTTP síncrono minimalista,
800# evita pull de tokio en el engine.
801html5ever = "0.39"
802markup5ever = "0.39"
803markup5ever_rcdom = "0.39"
804cssparser = "0.35"
805url = "2"
806# `gzip`: sin ella ureq ni anuncia `Accept-Encoding` ni decodifica la respuesta.
807# python.org (detrás de Fastly) devuelve `content-encoding: gzip` AUNQUE no se lo
808# pidan, y el cuerpo comprimido se decodificaba como UTF-8: 3.911 caracteres
809# U+FFFD y una página de 16 cajas en vez de 1.489. Además baja lo que se
810# descarga en todo el resto.
811ureq = { version = "2", default-features = false, features = ["tls", "gzip"] }
812# Charset de la web real: no todo es UTF-8 (google.com sirve ISO-8859-1).
813# Ya venía transitivo por el stack de Servo — aquí se hace explícito.
814encoding_rs = "0.8"
815
816# === takiy-synth (SoundFont MIDI) ===
817# rustysynth = sintetizador SF2 puro Rust, MIT. Reemplaza el oscilador
818# feo de takiy-synth por muestras reales (FluidR3, GeneralUser GS, etc).
819rustysynth = "1.3"
820
821# === takiy-playback (audio device output) ===
822# cpal = backend de audio cross-platform (ALSA/PulseAudio/Pipewire en
823# Linux, WASAPI en Windows, CoreAudio en macOS). Lo usamos sólo para
824# abrir el device default y empujar muestras f32 — nada de mezclado
825# ni efectos en el callback.
826cpal = "0.15"
827
828# === media-source-wav (decoder PCM en disco) ===
829# hound = lector/escritor WAV puro-Rust, sin deps nativas. Soporta PCM
830# entero (8/16/24/32) y float (32). Suficiente para abrir samples y
831# stems de prueba sin meter ffmpeg/symphonia.
832hound = "3.5"
833
834# === media-source-{mp3,flac,vorbis} (decoders vía symphonia) ===
835# symphonia es una colección de decoders puro-Rust mantenida. `mp3` cubre
836# media-source-mp3; `flac` (decoder + demuxer FLAC nativo) cubre
837# media-source-flac (lossless); `vorbis` + `ogg` (codec + demuxer Ogg)
838# cubren media-source-vorbis (lossy clásico, libre de patentes). Sin aac:
839# ese tier patentado entra por shared/foreign-av.
840symphonia = { version = "0.5", default-features = false, features = ["mp3", "flac", "vorbis", "ogg"] }
841
842# === media-source-opus (decoder Opus NATIVO puro-Rust) ===
843# Opus es el formato de audio nativo de tawasuyu (par del video AV1). ogg
844# demuxea las páginas Ogg; opus-wave es un port puro-Rust de libopus
845# (SILK+CELT, sin C ni FFI) — par del rav1d del lado video.
846ogg = "0.9"
847opus-wave = "3"
848
849# === media-source-webm (demux nativo Matroska/WebM) ===
850# matroska-demuxer es un demuxer puro-Rust de MKV/WebM (EBML). Saca los
851# paquetes de los tracks V_AV1 y A_OPUS para alimentar a media-source-av1
852# y media-source-opus — un .webm AV1+Opus se reproduce 100% nativo.
853matroska-demuxer = "0.7"
854
855# === Perfil `dist`: binarios de reparto livianos (equipos chicos / poca RAM) ===
856# Hereda de `release` pero prioriza HUELLA sobre tiempo de compilación: LTO thin
857# (poda código muerto entre crates), un solo codegen-unit (mejor inlining/DCE) y
858# `strip` de símbolos. Reduce el tamaño en disco Y el segmento de código mapeado
859# en RAM de cada binario (mirada, pata, apps Llimphi). No toca `cargo build
860# --release` de iteración diaria; se usa sólo al empaquetar:
861#   cargo build --profile dist -p mirada-compositor -p pata-host …
862# `panic = "unwind"` se mantiene a propósito: mirada-plugin-host aísla plugins
863# con `catch_unwind`, así que `abort` rompería el sandbox.
864
865[profile.dist]
866inherits = "release"
867lto = "thin"
868codegen-units = 1
869strip = "symbols"
870panic = "unwind"
871
872