El contenedor ahora es una opción (Ajustes) con defaults por modo:
- vigilia nocturna → AAC crudo (ADTS .aac): a prueba de cortes, si el
proceso muere a media noche el archivo se reproduce hasta donde llegó
(no depende de un índice final).
- grabar / reunión → .m4a (MP4): mejor búsqueda; son sesiones atendidas.
Refactor del codificador: interfaz Codificador + base común (posee el
MediaCodec AAC-LC) + dos contenedores (CodificadorM4a con MediaMuxer,
CodificadorAac que escribe frames ADTS con su cabecera de 7 bytes a un
flujo plano). Factoría crearCodificador(formato, ...).
Sesion/Repositorio guardan "fmt" (sesiones viejas = .m4a); el nombre de
archivo usa la extensión del formato. Ajustes: formatoVigilia (def AAC) y
formatoDia (def M4A) con selector en la pantalla de ajustes.
NO compilado aquí (sin SDK en este equipo).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Nuevo Modo.REUNION que transcribe lo hablado sin tocar la liviandad de la
noche: vigilia y grabación normal no ejecutan nada de STT (transcriptor
solo se crea en reunión).
- audio/Transcriptor: Vosk offline en hilo propio (cola productor/
consumidor) alimentado del mismo PCM que ya captura la Grabadora, así el
reconocimiento pesado no retrasa el hilo de audio ni ensucia el .m4a. El
reconocedor se reinicia por fragmento → cada fila del log lleva su texto.
- modelo (~45 MB) no va en el APK: se descarga y descomprime la 1ª vez
(ModeloScreen con progreso); luego todo offline. Reunión fuerza 16 kHz.
- Segmento gana texto (persistido en log.json como "txt"); mutaciones de
segmentos sincronizadas entre el hilo de captura y el de Vosk.
- UI: 3ª acción "reunión", texto en vivo en GrabandoScreen, texto por
fragmento en el log, distinción de color (rosa) en las listas.
- dep nueva libs.vosk.android (solo :vela); permiso INTERNET para bajar
el modelo.
Formato de audio se queda en .m4a (AAC) por decisión del usuario.
NO compilado aquí (sin SDK en este equipo).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Nueva app del rizoma :vela (com.rizoma.vela). Graba con AudioRecord (PCM
16 kHz mono), pasa cada cuadro por una puerta de voz adaptativa con
histéresis, pre-roll y cola, y solo codifica lo que suena → AAC/.m4a
(MediaCodec+MediaMuxer, sin deps ni LAME). Los silencios no se guardan:
el audio queda contiguo y compacto, y el log de diálogo registra los
tiempos reales.
- log de diálogo: línea de tiempo de fragmentos (hora, duración, nivel)
con silencios colapsados; persistido en log.json (atómico) por sesión.
- vigilia nocturna: foreground service tipo micrófono + wakelock parcial;
en silencio solo calcula RMS (barato) → ahorra batería con pantalla
apagada.
- UI Compose rizoma: medidor de onda en vivo, reproducción del audio
compactado con salto por fragmento, y ajustes (sensibilidad, pre-roll,
cola, calidad, mantener pantalla).
NO compilado aquí (sin SDK en este equipo).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Conector UnifiedPush 2.5.0 + ConsolaPushReceiver: registra con el
distribuidor (app ntfy), manda el endpoint al gateway (/register) y al
recibir un push muestra la notif. Notificaciones extraídas a Alerts
(compartido WS+push) con dedup por id. Sin Google ni Play Services.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
La notif de aviso ahora trae acciones que inyectan al PTY exacto vía
PtySendInput sin abrir el terminal: RemoteInput 'responder' (texto +
Enter), '⏎ continuar' (CR) y 'esc'. El servicio carga config fresca de
Settings (robusto con la app cerrada) y cancela el aviso tras actuar.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El evento trae shuma_session (el ULID que el daemon siembra en el PTY).
La notificación lo lleva como extra; MainActivity (singleTask + onNewIntent)
lo enruta a ConsolaViewModel.openFromNotification, que se adjunta a ese
terminal exacto.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Edge-to-edge dibujaba la fila de teclas detrás de la barra de
navegación. Ahora respeta WindowInsets.ime ∪ navigationBars: se sube
sobre el teclado cuando está abierto y sobre los botones del sistema
cuando no. Barras superiores con statusBarsPadding y FABs de la lista
con navigationBarsPadding.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- spawn vía login shell que prepende los bin del usuario al PATH
(~/.npm-global/bin, donde vive claude; el daemon arranca con PATH
mínimo). Antes 'ni siquiera encontraba claude'.
- nueva sesión por defecto: 'claude --dangerously-skip-permissions'
(modo danger) + botón flotante '+ claude' de un toque.
- fila de teclas del terminal: ctrl/alt pegajosos (modifican la
siguiente tecla), PgUp/PgDn/Home/End además de esc/tab/flechas.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El foreground service abre un WS de larga vida a /ws/events y, ante cada
evento de hook (Notification/Stop), levanta una notificación de alta
prioridad (canal 'avisos de Claude'). Reconecta solo y sobrevive a la app
en segundo plano. GatewayClient.openEvents + EventsConnection.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El layout del terminal disparaba resize() antes de que onOpen enviara
el open; OkHttp respeta el orden de envío, así que el resize se colaba
como primer frame y el gateway lo tomaba por apertura → "falta
'session' o 'program'". OpenGate difiere los resize hasta que el open
ha salido y suelta el último pendiente.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Vuelca DebugLog.dump() al portapapeles para compartir el log de
conexión (URL, handshake WS, errores) sin adb.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dos variantes nuevas (18 en total): Argyle (clásico + diagonales en rombo que
no repiten 1-9) y Cadenas/Chain (cajas sustituidas por cadenas serpenteantes de
9 celdas, vía camino hamiltoniano "backbite").
Arreglo importante de generación de regiones: el solver ahora lleva presupuesto
de nodos, así una distribución irresoluble se descarta en vez de colgar el
backtracking (antes Chain podía colgar la generación). Y el generador jigsaw
—que se atascaba y degeneraba silenciosamente en cajas 3×3— se rehízo con
Voronoi (semillas en centros de caja con jitter) + rebalanceo conexo: ahora
produce regiones irregulares de verdad y resolubles (~94% irregulares, el resto
cae a cajas como respaldo seguro). Verificado: 18 variantes × 4 dificultades,
todas válidas, únicas y sin cuelgues.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Variantes nuevas (16 en total): Rascacielos (visibilidad desde el borde),
Little Killer (sumas en diagonales) y Rossini (orden de las 3 celdas del borde).
El motor suma restricciones de visibilidad y diagonales-suma, con marco de
pistas alrededor del tablero.
Dificultad de verdad: fácil/medio se resuelven solo con lógica (singles), y
difícil/experto permiten razonamiento avanzado dejando muchas menos pistas
(23-30 vs 34-44). Verificado para las 16 variantes × 4 dificultades.
Menú rediseñado: pager horizontal arrastrable, una página por variante que
dibuja su forma particular (diagonales, ventanas, jaulas, flechas, etc.) con
su selector de dificultad y el historial de puzzles generados/cumplidos.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Motor generalizado: regiones irregulares, máscara de paridad por celda,
restricciones binarias entre vecinos y jaulas con suma — todo sobre el mismo
solver/cavado con solución única (verificado para 13 variantes × 4 dificultades).
Teclado reorganizado: las 6 acciones pasan a columnas izquierda (deshacer/
rehacer/comprobar) y derecha (edit/borrar/pista) del 3×3. Overlays por variante:
bordes de región, sombreado par, marcas de arista (barra/X/V/‹›) y jaulas
punteadas con su suma.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Familia de "región extra" sobre un único motor (genera + soluciona con solución
única, verificado para las 7 × 4 dificultades): Clásico, X, Windoku, grupos
disjuntos, punto central, asterisco y girándola. Generación determinista por
(variante, dificultad, índice); persiste cuántos se generaron, el avance de
cada uno (rejilla + notas) y los completados. Dinámica "elige número → toca
celdas", con teclado deshacer/rehacer/comprobar, 3×3 y edit(borrador)/borrar/pista.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diccionarios expandidos (~40k entradas) y cambios en SuggestionEngine que ya
estaban en el árbol de trabajo de una sesión previa; se commitean tal cual.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
onUpdateSelection ahora detecta el toque del usuario y finaliza la composición
en su sitio (antes el siguiente carácter saltaba a la posición vieja). Las
mayúsculas pasan al swipe ↑ de la R; la columna derecha queda emoji / ?123 /
borrar / enter y el espacio ocupa toda la fila inferior.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El servicio ya no hace reset() ciego: restaura el tablero guardado (celdas +
score + won) si encaja con el tamaño del cubo, guarda tras cada jugada y borra
al perder (el récord ya queda sellado aparte).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Guarda la disposición de cada nivel sin resolver y la reanuda al reabrirlo;
el mapa muestra los empezados a medio brillo con etiqueta "en curso". Barajar
descarta el parcial; resolver lo limpia.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nueva DebugLog (singleton observable por Compose) que registra cada paso
de RPC y del WebSocket. El panel se abre solo al fallar; el EOFException sin
respuesta ahora trae una pista interpretada. Antes todo iba solo a Logcat.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Juego nuevo (app independiente :cubo): rejilla 3×3×3 con las seis
direcciones de caída (ejes X/Y/Z × ±1), fusiones tipo 2048 por líneas,
récord persistido en DataStore.
Render OpenGL: cubos coloreados y numerados (atlas de texturas),
iluminación por normales, ordenados de atrás-adelante y mezclados con
alfa (slider "ver dentro" para la transparencia). Rotación arrastrando
+ auto-giro en reposo y "pop" al aparecer baldosas. Gnomon de ejes
(X rojo, Y verde, Z azul) que orienta las caras; botones de dirección
coloreados igual.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El tablero deja de forzarse cuadrado y llena el área disponible con el
ratio de la pantalla, así las baldosas heredan la forma del display en
todos los niveles. La progresión de formas escala ahora hasta 13×13,
repartida proporcionalmente por los 48 niveles base.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ConsolaService.consume no compilaba con Kotlin 2.2.0 (when no exhaustivo:
el var ev no recibía smart-cast a no-nulo). Por eso el diagnóstico de WS
nunca llegaba al APK instalado. Se fija con `val e = ev ?: break`.
GatewayClient: el token iba crudo en el query del WS; un '+', '/' o '='
(base64/JWT) rompía el handshake (401/400) aunque funcionara por header
en /rpc. Ahora va con URLEncoder.encode. Además, fallo de WS con stack
completo a Logcat (tag ConsolaWS) + cuerpo de respuesta HTTP, y detalle
en pantalla que nunca queda vacío (incluye la URL si no hay respuesta).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cada cabecera de dificultad lleva un chip "✦ +4" que genera 4 niveles
extra de esa misma banda, persistentes (DataStore, prefijo "g:"). La
generación se desacopla de la semilla: los ids generados viven en un
espacio propio por dificultad (GEN_BASE + tier*STRIDE + k) y heredan la
forma/fijas de un nivel representativo del tramo, con semilla nueva →
puzzle distinto pero de la misma dificultad. Niveles generados marcados
con ✦, navegables dentro de su tramo, sin tocar el progreso lineal.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
onFailure tiraba el mensaje útil: una caída de handshake llegaba como
"fallo del WebSocket" a secas (t.message null). Ahora reporta clase de
excepción + código HTTP de la respuesta, para distinguir 401, conexión
rechazada, proxy sin upgrade o TLS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El WS al shuma-gateway (y el socket al daemon Rust) ahora lo posee un
ConsolaService de primer plano (tipo dataSync), no el ViewModel. Así
Android no mata la sesión TUI al perder el foco. Notificación persistente
"[ sesiones de consola vivas ]" con acento neón y acción "detener"; la UI
se une/separa del servicio y restaura el terminal si sigue vivo al volver.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
La pantalla principal pasa a ser un MAPA del viaje completo (48 niveles)
agrupado por dificultad (fácil/ameno/difícil/experto/maestro): cada nivel se
dibuja como su propio degradado en miniatura, los resueltos brillan con anillo y
su mejor marca, los pendientes quedan atenuados. Todos caben en filas de cuatro.
- Progreso persiste ahora los logros: conjunto de niveles resueltos y mejor marca
(mínimo de movimientos) por nivel, en DataStore. El ViewModel los observa para
que el mapa los refleje al instante; al resolver se sella resuelto+mejor.
- Navegación Mapa↔Juego; "‹ mapa" y atrás vuelven al mapa.
- El tablero ya encaja en pantalla (aspectRatio con matchHeightConstraintsFirst).
Escrito NO compilado aquí.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El launcher pasa de una sola vista a cinco páginas que se arrastran de izquierda
a derecha; el átomo es UNA pieza que se desliza tras ellas (continuidad real),
no cinco copias. Páginas: 1.clima · 2.nuevas+pedazo · 3.centro del átomo ·
4.pedazo+expulsadas · 5.desterradas.
- Paginado continuo propio (pos 0..4) con draggable + animate/spring; el cuerpo
no se recompone por fotograma (graphicsLayer/derivedStateOf leen pos diferido).
- nuevas: apps recién instaladas (<3 días, sin abrir) flotando caóticamente
"esperando entrar"; al abrirlas entran al átomo.
- expulsadas: las quitadas del átomo se alborotan (jitter ∝ turbulencia) y se
calman con el tiempo; a los 7 días pasan a desterradas (ya quietas, página 5).
AppNode gana firstInstallTime y hiddenAt; UsageStore sella el instante de
expulsión (snapshot() unifica toda la memoria orbital en una lectura).
- clima (página 1): temperatura+condición sobre el cielo vivo; abre Nimbo si está.
- Optimización: cada zona se compone solo cerca de su página y el clima solo se
pide (permiso+red) al acercarse — mientras no se abra, no se carga.
Escrito NO compilado aquí.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
App insignia del set: las notas son nodos conectados por enlaces [[wikilink]],
navegables como grafo en vez de lista jerárquica.
- Persistencia sin deps: un notas.json en filesDir (org.json), escritura atómica
(.tmp + rename) con debounce 350ms; siembra de bienvenida al primer arranque.
- Enlaces [[titulo]] resueltos por título normalizado; aristas dirigidas,
backlinks (retrocesos) y enlaces "fantasma" que crean la nota al tocarlos.
- Vista grafo: lienzo paneable/zoomable (detectTransformGestures, escala 0.4–3),
nodos arrastrables con burbuja+halo neón, tamaño por grado; FAB para crear.
- Editor: título+cuerpo (BasicTextField), chips de enlaces en vivo y lista de
retrocesos; autosalvado.
- Navegación por estado (Grafo|Editor), sin librería. Estética rizoma, offline.
Generado con un subagente bajo spec estricta; escrito NO compilado aquí.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
App de clima donde el cielo vivo ES la interfaz: reutiliza el motor de fondo de
Órbita (manchas Lissajous con mezcla aditiva cuya paleta deriva de hora local +
clima) a pantalla completa, y encima pinta un pronóstico real.
- Datos Open-Meteo sin clave ni deps (HttpURLConnection): actual + 24h + 7 días,
con timezone=auto. Ubicación aproximada del sistema (last-known) y geocoding
inverso (Android Geocoder) para el nombre del lugar.
- Hora local del lugar calculada al vuelo desde utc_offset → el cielo es correcto
aunque el dato venga de caché.
- Caché del último pronóstico en DataStore (JSON crudo): abre al instante/offline
y refresca en segundo plano.
- Glifos de clima monoline dibujados a mano en Canvas (sol/luna, nube, niebla,
lluvia, nieve, tormenta), sin emojis.
- UI: temperatura grande, métricas (sensación/viento/humedad), franja por horas
con prob. de precipitación, lista de 7 días con barras frío→cálido.
- Permiso de ubicación pedido en runtime; estados de carga/permiso/error.
- Estética del rizoma: neón sobre vacío, español minúscula. minSdk 26, sin clave.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rejilla de baldosas de color plano: las esquinas (y algunas más en niveles
fáciles) quedan fijas y el resto se baraja. Se arrastra una baldosa sobre otra
para intercambiarlas hasta reconstruir el degradado 2D. Al resolver, el hueco
entre baldosas y el redondeo se desvanecen: el degradado se vuelve continuo.
- Niveles autogenerables y deterministas por seed (SplitMix64): el mismo número
de nivel produce el mismo puzzle en cualquier dispositivo, así es compartible.
- Interpolación bilineal en CIELab (no sRGB) para degradados perceptualmente
suaves; esquinas sembradas en HSV con matiz horizontal y brillo vertical.
- Dificultad creciente: la rejilla crece (3x3 → 6x8) y las baldosas fijas
decrecen con el nivel.
- Detección de resuelto por ΔE (tolera baldosas casi idénticas).
- Progreso (nivel actual/máximo) persistido en DataStore.
- Estética del rizoma: neón sobre vacío, háptica al intercambiar.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
App (com.rizoma.consola) para administrar y operar las sesiones PTY
persistentes del shuma-daemon a través del shuma-gateway. Tercera app del
rizoma, misma estética neón.
- Transporte (data/): GatewayClient sobre OkHttp — POST /rpc (JSON 1:1 con
org.json, serde externally-tagged) y GET /ws/pty (WebSocket full-duplex).
Protocol.kt: modelo PtySession + builders/parsers de PtyList/PtySpawn/
PtyKill. Settings.kt: URL del gateway + token en DataStore.
- Emulador (term/TerminalEmulator.kt): vt100/xterm propio sin dependencias
— UTF-8, CR/LF/BS/TAB, cursor (CUP/CUU/CUD/CUF/CUB/CHA/VPA), borrado
(ED/EL/ECH), insert/delete de líneas y caracteres, región de scroll
(DECSTBM), índice/índice inverso, SGR 16/256/truecolor con negrita e
inverso, pantalla alterna (?1049/?47) y visibilidad de cursor (?25).
Produce TerminalFrame inmutable para renderizar.
- UI (ui/): SessionListScreen (lista viva/muerta + crear/matar + diálogo de
spawn), TerminalScreen (render en Canvas con runs por estilo + cursor,
entrada por campo oculto + onPreviewKeyEvent + fila de teclas especiales),
SettingsScreen, ConsolaApp (navegación) y Theme.
- ViewModel: lista vía /rpc; terminal por canal de bytes → emulador →
frame Compose; reescalado del PTY al medir la rejilla; detach al salir.
- Gradle: :consola en settings, OkHttp 4.12 en el version catalog,
minSdk 26 / targetSdk 36 / JVM 17, Compose BOM. README con cómo conectar.
No compilado aquí (sin Android SDK en este equipo); el build/run va en la
máquina con la toolchain.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Háptica: ime/Haptics (Vibrator + VibrationEffect, permiso VIBRATE) con
intensidad suave/medio/fuerte; el KeyboardController la dispara en cada
acción (cursor con tick suave).
- Palabra siguiente: SuggestionEngine aprende bigramas (b:prev>next,
persistidos) y predice tras espacio/sugerencia, encadenable; filtra a
palabras conocidas para no propagar erratas. Diccionarios separados es/en.
- Emojis: nueva Layer.EMOJIS con catálogo (model/Emoji) y panel desplazable
(ui/EmojiGrid, recientes incluidos); tecla 😊 en la fila de funciones.
- Ajustes: data/TrazoSettings (DataStore reactivo, estado Compose compartido
entre IME y Activity) + pantalla en MainActivity con toggles de vibración
e intensidad, doble-espacio→". " e idiomas de predicción es/en.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Nuevo: ocultar un nodo lo retira del átomo pero la app sigue instalada;
se restaura desde la búsqueda (long-press → "devolver al átomo"). Los
ocultos aparecen atenuados y marcados en la búsqueda. Menú distingue ya
"quitar del átomo" de "desinstalar".
- Fondo dinámico: paleta del cielo derivada de la hora del día (anclas
noche/alba/mediodía/ocaso interpoladas) y modulada por el clima local
(Open-Meteo, sin clave ni dependencias; ubicación aproximada del sistema).
Transiciones suaves entre cielos.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Mapa de swipes reemplazado por el layout MessagEase real (verificado contra la
fuente de Thumb-Key, sucesor FOSS): A↘v N↓l I↙x H→k R←m T↗y S↖f; centro O con
↖q↑u↗p→b↘j↓d↙g←c; E con w/z/'/:/./, . Añadida Ñ (↑ en la N) para español.
- navigationBarsPadding en el teclado para que la fila de funciones (?123, espacio,
borrar, enter, shift) no quede tapada por la barra de navegación.
Ref: github.com/dessalines/thumb-key (ENMessagEase.kt)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
La ventana del InputMethodService es internamente un Dialog; Compose resuelve el
ViewTreeLifecycleOwner desde el hijo de android.R.id.content (el parentPanel del
decor) hacia arriba, nunca a través del ComposeView. Se fijan los owners
(Lifecycle/ViewModelStore/SavedState) en el decorView de la ventana.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Órbita:
- Acción "alejar" en el menú: empuja a órbitas externas un nodo que se acercó
demasiado (penalización persistida sobre su calor; vuelve si se reusa bastante).
- Fondo dinámico: manchas de luz neón (verde/rosa/cian) que derivan en
trayectorias de Lissajous y laten, mezcladas de forma aditiva sobre el vacío.
Trazo:
- Aprendizaje "bueno": las palabras del diccionario se refuerzan al instante,
pero una palabra nueva entra a sugerencias solo tras escribirse 2 veces
(los typos de una vez no contaminan).
- Sugerencias bilingües: diccionarios es + en cargados juntos; salen en el
idioma del prefijo que se escribe. Sin autocorrección (solo capitaliza).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Barra de sugerencias: la palabra en curso vive como texto en composición
(subrayado); un toque la reemplaza por la sugerencia y deja espacio.
- SuggestionEngine: diccionario base en español (assets/dict_es.txt) + palabras
aprendidas y persistidas (DataStore), predicción por prefijo ponderada.
- Mantener ⌫ → borrado repetido; swipe horizontal en la barra espaciadora
mueve el cursor (toque = espacio).
- Controller reescrito sobre setComposingText/finishComposingText; abandona la
composición si el cursor sale (onUpdateSelection).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Módulo :keyboard (com.rizoma.trazo) — IME de trazos para español:
- Grid 3x3: un toque + ocho swipes por tecla, todo data-driven (KeyLayout).
Toques = letras frecuentes en posición MessagEase clásica (A N I / H O R / T E S);
secundarias frecuentes en los swipes del centro (O), raras y Ñ en los bordes.
- Capa de números/símbolos conmutable.
- Gestos: detección tap vs. 8 direcciones por ángulo del delta del dedo.
- Lógica inteligente: auto-mayúscula según el editor (getCursorCapsMode),
doble-espacio → ". ", shift one-shot / bloqueo, enter contextual (editor action).
- Teclado Compose hospedado dentro del InputMethodService (lifecycle/savedstate
owners cableados al ComposeView).
- Activity de configuración para activar y elegir Trazo.
settings.gradle: :keyboard habilitado.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Primera versión funcional del launcher del rizoma:
- Carga de apps lanzables vía PackageManager con iconos rasterizados.
- Disposición orbital: nodos en órbitas concéntricas según su calor (uso);
fijados y más usados caen a órbitas internas. Anillos contrarrotantes.
- Toque para lanzar, mantener para menú (fijar/soltar, info, quitar).
- Núcleo central pulsante → búsqueda en vivo sobre todo el rizoma.
- Persistencia de uso y fijados con DataStore; refresco ante instalar/desinstalar.
Build: añade material3 y lifecycle-viewmodel-compose; :keyboard pospuesto.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>