astra
alpha-0.1-background
alpha-0.1-dir-prefs
alpha-0.1-sec-dom
menubar-v4-safe
active-uix
morfo-runtime
morfo-driven-soma
semantuix
glm-5
main
sium-v1.0
${ noResults }
197 Commits (b59332132f551065f4a9c9a908e3ec0769d72bcc)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
b59332132f |
feat(blocks): F2.5 `testimonials` — rejilla de citas con autor
Prueba social: una cabecera sobre una rejilla responsive de tarjetas de cita, cada una con su autor (avatar · nombre · cargo). Compound —la `.Item` se repite, como feature-grid— y SIN contexto (las partes no coordinan). `<Testimonials>` + `.Header` + `.Items` + `.Item` + `.Quote` + `.Author`(slot `avatar` + `.AuthorName`/`.AuthorRole`). - `AutoGrid` de tarjetas de igual alto; `.Author` fijada al borde inferior de la tarjeta (`margin-block-start: auto`) para que una fila de citas de distinto largo alinee las caras. - La cara es del app: un `<Avatar>` con imagen o un `Avatar.Fallback` de iniciales va en el slot `avatar` (B-7). - La tarjeta del quote usa `variant="outline"` — el `soft neutral` es casi invisible en claro. Encontrado al componer (en el README del block): el tema activa solo un SUBCONJUNTO de escalas donor (`green/indigo/orange/plum/teal`); una escala no activada (`cyan/ruby/amber/jade`) en `color` cae en SILENCIO a `primary` (la regla `[data-color]` hace `var(--scale-…, primary)`). Config del tema, no bug de componente; la demo usa escalas activadas. Hueco a decisión del usuario (Gaps): la **cita única en spotlight** (grande, centrada, logo+avatar+autor) — la variante modal del dossier, el grid es minoría. Otra disposición → candidato a hermano `testimonial-spotlight`. Demo (`web/routes/blocks/testimonials/`): full-bleed + ruta `preview`, cinco citas con avatares de iniciales en cinco colores distintos. Verificado en claro/oscuro × LTR/RTL, caras alineadas al fondo. `blocks:check` verde (6 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
594e5a5db4 |
feat(blocks): F2.4 `pricing` — el primer compound CON CONTEXTO del tier
La sección de planes: un toggle de periodo sobre una fila de planes, uno destacado. Es el primer block cuyas partes se COORDINAN de verdad (no solo se repiten como en feature-grid/split): el `Switch` escribe el periodo de facturación y cada `PlanPrice` lo lee. Esa coordinación es lo que gana un contexto compartido — la forma más fuerte de compound. `<Pricing bind:period>` + `.Header` + `.Switch` + `.Plans` + `.Plan`(featured, badge) + `.PlanName`/`.PlanDescription`/`.PlanPrice`/`.PlanFeatures`/ `.PlanFeature`/`.PlanAction`. - **Contexto reactivo** (`context.ts`): la raíz provee el periodo como getter sobre un `$bindable`; el `Switch` (un `ToggleGroup`) lo escribe, el `PlanPrice` lo lee y muestra el snippet `monthly` o `annual`. Mismo patrón que `CardGroup`. `period` es bindable por si la app quiere observarlo. - **El block NUNCA formatea moneda**: la app compone `FormatNumber` dentro de los snippets de precio (B-7). El block posee el switch, no el dinero. - `.PlanAction` fija el CTA al borde inferior de la tarjeta (`margin-block-start: auto`) para que una fila de planes alinee sus botones aunque tengan distinto nº de features; `.Plan` con `align="start"` deja los checks en columna limpia; `featured` da acento (borde primary) + elevación. Demo (`web/routes/blocks/pricing/`): full-bleed + ruta `preview`, tres planes (Pro destacado en el centro) con el toggle mensual/anual vivo. Hueco a decisión del usuario (Gaps del block): la **tabla de comparación** (features × planes) — la brecha recurrente del dossier en pricing. Es una tabla, no una fila de tarjetas: candidato a hermano `pricing-table`. Presentado, no resuelto. Verificado en navegador: el toggle cambia los TRES precios a la vez (0/29/99 → 0/23/79), tarjetas de igual alto con CTAs alineados, featured con acento, en claro/oscuro × LTR/RTL. `blocks:check` verde (5 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
cd399f7c7c |
fix(eidos): el `align`/`justify`/`alignContent` de `Grid` sí aplican
`<Grid align="center">` no tenía efecto: `align-items` computaba `normal`. Los atajos `place-items`/`place-content` del recipe se emiten DESPUÉS de los longhands, y su fallback `revert-layer` —cuando el prop `placeItems`/ `placeContent` no está puesto— revertía el longhand anterior a su valor inicial, pisando en silencio lo que `align`/`justify`/`alignContent` escribían (un atajo posterior gana sobre el longhand que expande). Ahora el fallback de los atajos COMPONE los vars de los longhands en vez de revertir; si el prop del atajo sí está puesto, sigue ganando (va el último). Los grids por defecto no cambian (para ítems de grid, `align-items: normal` ≡ `stretch`). Encontrado al alinear las filas de `feature-split`. Verificado: `vitest src/uix/eidos` 353/353 · en el navegador, feature-split (filas centradas), el chart del Mockup (`align="end"` = barras a la base) y feature-grid (AutoGrid, sin cambio). Doctrina en theming/changelog §47. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
08ea82d128 |
feat(blocks): F2.3b `feature-split` — la brecha nº1 del dossier, con Mockup
La sección que las 5 refs shippean y que va justo tras el hero: una afirmación de producto junto a un screenshot, alternando lados fila a fila. Otra disposición que la rejilla de iconos de `feature-grid`, así que block hermano (decisión del usuario), no una variante turbia dentro de aquél. Compound —la `.Row` se repite—: `<FeatureSplit>` + `.Row` (`reversed`, slot `media`) + `.Eyebrow` + `.Title` + `.Text` + `.Features`/`.Feature` (checklist) + `.Actions`. El block coloca; la app pone la copy y la media. - `reversed` mueve la media al lado de inicio vía `grid-column` (Box expone `gridColumn`/`order`), dejando la copy SIEMPRE primera en el DOM — el orden de lectura y el foco no cambian aunque el screenshot salte de lado. - El check de cada `.Feature` es decorativo (`aria-hidden`): la palabra lleva el significado. - La media se COMPONE con el primitivo `Mockup`: la demo enseña cromo de navegador (dashboard) y de teléfono (app), cerrando el hueco de «tratamiento de media» del dossier de raíz en vez de falsearlo. `.Row` usa un tipo limpio (no `HTMLAttributes`) porque su slot `media` colisiona con el atributo HTML homónimo; el resto de sub-partes extienden los props del componente canon que envuelven (lección de feature-grid). Demo (`web/routes/blocks/feature-split/`): full-bleed + ruta `preview`, con control del nº de filas y del lado inicial; 3 filas con Mockup navegador/teléfono. Verificado en navegador (Playwright, módulos frescos): filas alternas en claro/oscuro × LTR/RTL, `reversed`, el orden de lectura copy-primero, y los dos cromos de Mockup. `blocks:check` verde (4 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
d01b3e6af5 |
feat(blocks): F2.3 `feature-grid` — el primer block compound del tier
`<FeatureGrid>` + `.Header` + `.Items` + `.Item` + `.ItemIcon`/`.ItemTitle`/ `.ItemText`: una cabecera sobre una rejilla responsive de features (icono · título · texto). Es la sección que responde «qué hace», la nº1 tras el hero. Primer block COMPOUND del tier, y aplica la regla de forma que fijamos: el `.Item` se REPITE (el app mapea sobre N features) → gana sub-componentes, donde `hero`/`site-header` usan slots de snippet (partes fijas de layout). Las partes no coordinan —sin contexto ni estado entre ellas—: la rejilla es del padre, las celdas del app. `.Items` es el envoltorio honesto de la rejilla (`AutoGrid`), que deja la cabecera fuera sin un `grid-column: 1/-1` a pelo. - El block coloca (Section · Container · AutoGrid · Surface · Heading · Text); el app pone todo el contenido por children (B-7). - `.Items` fluido por `minChildWidth` (tantas columnas como quepan) o `columns` fijas; `.Item` `align` start/center; `.ItemIcon` chip `Surface`; `.ItemTitle` `Heading` h3; `.ItemText` `Text` apagado. - `align` de sección (center/start) coloca la cabecera coherente con las columnas. Dos cosas encontradas al construir, resueltas: - **Los sub-componentes de bloque extienden los props del componente canon que envuelven** (`BoxProps`, `StackProps`, `HeadingProps`…), **no `HTMLAttributes`**: el `style: string|null` del atributo HTML crudo choca con el `style: string` del canon al hacer spread (+ "union type too complex"). - **`.ItemIcon` por defecto `solid`, no `soft`**: el soft-primary en claro es casi blanco (oklch 0.99) → el chip era invisible; solid da el chip con glifo on-solid (la tinta de contraste la pone `Surface`). Demo (`web/routes/blocks/feature-grid/`): full-bleed + ruta `preview`, con control de columnas (fluido/2/3/4), align, nº de items y dir; 6 features con iconos del canon. Hueco a decisión del usuario (en los Gaps del block): el **feature-split/ alternante** (texto junto a un screenshot, lados alternos) — la brecha nº1 del dossier — es otra disposición (filas de 2 columnas, no rejilla de iconos): probablemente un block hermano `feature-split`. Presentado, no resuelto. Verificado en navegador (Playwright, módulos frescos): center/start × claro/ oscuro × LTR/RTL, columnas fluidas y fijas, 3/4/6 items, chips visibles. `blocks:check` verde (3 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
5125502486 |
feat(blocks): F2.2 `hero` — center · split · background, por slots
Segundo block del tier. API por SLOTS DE SNIPPET, no compound: la forma se razonó con el usuario y con el paisaje de referencia. Compound se reserva para partes que COORDINAN (estado/contexto/ARIA entre ellas — Accordion, Dialog); un hero son cinco slots de layout que no se hablan entre sí y que el root arregla, así que snippets. Además el campo entero shippea marketing como copy-paste plano —nadie aplica compound a una sección—, y los slots por zona son la historia de personalización que distingue al tier del copy-paste. `<Hero layout="center|split|background" level container size>` + `eyebrow/title/description/actions/media/background/children`. - El block **envuelve** título y subtítulo en `Heading`/`Text`: así posee el `id` que nombra el `<section aria-labelledby>` y el nivel del encabezado, mientras la app pone las palabras (B-7). `eyebrow`/`actions`/`media` son contenido libre (ahí los componentes del canon SON la API). - `center` = `Stack` centrado, media debajo (ancho-capado); `split` = `Grid` de dos columnas (una sola sin media), apila en estrecho. - **`background` (cover)** — añadido por scope-approval del usuario: la media a sangre detrás de la copy, con velo de contraste (`--color-overlay` a `--opacity-scrim`), texto `on-solid` y `object-fit: cover` vía un `<style>` justificado (D-BLK.2). Son las ÚNICAS reglas que el block posee, todas sobre tokens del ecosistema — cero color a mano. Capas por orden de fuente, sin `z-index`. Demo (`web/routes/blocks/hero/`): full-bleed en la página + ruta `preview` para anchos de dispositivo, cada prop un control vivo, y el backdrop del layout cover dogfooda el sistema de color — es un `Surface color="primary" gradient` (finish aurora = `--gradient-aurora`, derivado de los roles del tema; cambia con la paleta). Mini-site compartido por las dos superficies (`HeroSite.svelte`). Encontrado al componer, registrado no resuelto: `Box`/`Surface` `flex`/`grow` no hicieron crecer un hijo flex (bars a 0-width, `flex: 0 1 auto`; la prop no la usa ningún componente shipped). La demo usó `Grid` (tracks `1fr`). Flag en el README del block y en el handoff para revisar el cableado de `--box-flex`. Verificado en navegador (Playwright headless, módulos frescos): center/split/ background × claro/oscuro × LTR/RTL, media on/off, y el landmark nombrado (región con `aria-labelledby` que resuelve al título). `blocks:check` verde (2 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
356ebf92af |
feat(button): el CTA que navega y parece botón, por composición (opción D)
El hueco que registró `site-header`: un «Empezar gratis» de cabecera tiene que
NAVEGAR y parecer botón. `Button` no crece un `href` —`Link` posee la
navegación, y un ancla se activa con Enter, no con espacio, lo cual es
correcto—: presta la pintura por composición. Lo que hacía de esa forma un
downgrade era que el `child` (asChild) descartaba la decoración; se completa el
slot.
- **eidos `<Button>`**: el `child` recibe ahora `content`, el cuerpo YA
decorado (icono · etiqueta · endIcon · spinner) en su propio snippet que
comparten las dos ramas de render. Así
`<a href {...props}>{@render content()}</a>` conserva TODOS los slots en vez
de sustituirlos (antes la flecha del sitio alpha estaba escrita a mano).
Nuevo tipo exportado `ButtonChildProps`.
- **soma / morfo**: en la forma `child` el elemento es del consumidor, así que
soma deja de estampar `type` (un `<a type="button">` es una pista de MIME
falsa). El componente pasa `type: undefined` cuando hay `child`; el provider
lo REENVÍA verbatim (antes lo re-defaulteaba a `'button'` y pisaba el drop —
el default vive en el destructure del componente); el morfo declara el attr
`type` condicional (`prop-truthy`).
- **docs**: ejemplo rancio de `index.ts` corregido (anunciaba un `asChild`/
`variant="link"` que no existen); sección «CTA que navega» en el README de
eidos con el patrón y el footgun documentado (un `<button>` en un `<form>` vía
`child` se pone su propio `type`); nota en el README de soma.
- **site-header**: el CTA de la demo usa ya la forma real (`<a>` sólido con
flecha), y el hueco pasa de «candidato a canon» a CERRADO por composición —
`Button` sigue sin `href` y `Link` sigue poseyendo la navegación, las dos
decisiones firmadas se mantienen. Actualizados PLAN/CONTINUE-blocks.
- **demo de Button**: control `child (asChild → <a>)` vivo, snippet del código
y fila de a11y explicando por qué el ancla activa solo con Enter.
Verificado en navegador (dev, restart para módulos frescos): asChild ON →
`<a href="#pricing">` sin `type`, pintura sólida completa (bg primary, tinta
blanca, 36px, padding 16px), y el slot de icono SOBREVIVE dentro del ancla
(`[data-button-icon]` + svg + body); asChild OFF → `<button type="button">`
intacto (sin regresión de submit implícito); el CTA real de `site-header` sale
`<a>` con la flecha final y 0 errores de consola. `blocks:check` verde ·
`vitest src/uix/morfo` 114/114 · `svelte-check` sin errores propios nuevos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
d38bd63faa |
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff
Documentación al día de lo que se cerró hoy y handoff para retomar mañana.
- `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la
fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu`
(arreglado en el canon, no parcheado en el block), el hueco del CTA que
navega y parece botón (registrado, no falseado) y el defecto de framework
que destapó la demo.
- `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de
heredarse. Un `Section` regalaba su padding a cada descendiente —la galería
arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display`
ajenos. `@property { inherits: false }`, radio verificado sin regresiones.
Lección: una variable que un componente escribe para SÍ MISMO debe declararse
`inherits: false`; si no, deja de ser un prop y se vuelve un contagio.
- `architecture/blocks.md` B-9: la demo de un block se construye sobre el
harness compartido y el block se enseña A SANGRE — nunca dentro de un marco
con relleno ni de una caja con scroll, porque eso cambia lo que el block
hace.
- `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta
`preview`, `DocRow`, catálogo único, ejes en el shell).
- `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla
de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe
solo para anchos de dispositivo, cada prop un control, nada de backticks en
`<Text>`, ojo con las variables que heredan), la deuda declarada que es
decisión del usuario y el estado exacto de los gates.
Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda
ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los
3 fallos ajenos conocidos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
ee02c5c55f |
docs(agent): D-AG.12 y §5b firmadas — la spec, y quién prueba el eje
Dos decisiones que estaban pendientes, firmadas tras investigación a fondo
(precedente externo verificado a fecha, no de memoria).
D-AG.12 — EL CONTRATO COMO REFERENCIA
Spec normativa en `docs/spec/` (RFC-2119 + IDs `AG-n` + escalera
stable|provisional|reserved + versionado por fecha), en estado DRAFT para que
F4b se construya CONTRA ella y no al revés. La doctrina se queda con el PORQUÉ.
Conformance en DOS vehículos, que es lo que evita que la palabra sea retórica:
kit de fixtures del protocolo (PORTABLE — un tercero lo corre contra SU
implementación; semilla ScriptedAgentTransport) + agent-check (lint del repo),
ambos citando IDs de requisito en sus fallos. Las dos claims de frontera se
nombran con marcador claimed|shipped porque hoy ninguna está materializada.
Gate de promoción a 1.0: ≥2 formas de dominio + claims shipped + fixtures
verdes. Respaldo externo: MCP ya no promueve a Final sin escenario en su suite
(SEP-2484) y opera lifecycle formal con ventana de 12 meses; AG-UI se volvió
referencia por ADOPCIÓN (AWS Bedrock AgentCore, Microsoft Agent Framework), no
por publicar suite. La spec se escribe antes para gobernar; el título se gana
después.
§5b — QUIÉN PRUEBA EL EJE: form + table
El gate de F4 pedía «2 manifiestos reales» sin asignar dueños; esto rellena ese
hueco, no enmienda nada. El criterio deja de ser disponibilidad y pasa a ser
dificultad: un formato lo decide su caso peor. Y form+table no son preferencia,
son la ANATOMÍA del contrato — los args de una capacidad SON schemas (sium →
toJsonSchema, ya construido en F1) y un run ES una transacción sobre un
conjunto de ediciones. Form además dobla: agente→componente (args contra
campos) y componente→agente (elicitación) son la misma proyección en los dos
sentidos.
Chat y palabras quedan como CONSUMIDORES, no jueces. El riesgo que esto evita
era real: ambos son texto lineal, así que un manifiesto probado solo ahí
habría asumido texto en silencio (rango como selección, ediciones
secuenciales, args string) y el caso peor habría aparecido tarde. Inventario
al firmar: 170 morfos, 0 con capacidad delegate declarada.
COROLARIO — la elicitación no depende de superficie conversacional
Una pregunta tipada es un formulario en contexto (Form.AutoFields), descartable
y no-modal, que es justo lo que exige el contrato a11y (WCAG 2.2.4). La nota de
protocol.ts («materializes with the conversation surface») describía UNA opción
y se leía como necesidad: corregida ahí y en la doctrina §7.
DESCARTADO
Entrada de delegación global siempre-disponible: roza el modo ambiental, que
está FIRMADO FUERA (⚖️1), y no se recupera por la puerta de atrás. La entrada
es un patrón con pieles montado en app-land — mismo veredicto que la
review-card.
Handoff `continue-agente-2026-07.md` reescrito para mañana: la spec DRAFT es lo
primero, luego el kit de fixtures, luego F4b con los dueños ya firmados.
Verificado: agent 30/30 · agent:check limpio · docs:check sin errores nuevos
(el único es el preexistente ajeno de callout).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
6b23aa7ef1 |
agent(guard): agent-check nace con la auditoría que ya tiene sujeto — anti-falsificación de actor
D-AG.11 (firmada) define SEIS auditorías. Cinco necesitan el árbol de manifiestos `src/uix/agent/components/`, que es trabajo de F4b — y el plan es explícito: el guard «nace CON el árbol, no después». Así que quedan DECLARADAS en el script y se reportan como pendientes: añadir un manifiesto las enciende, y el guard nunca puede ir por detrás de la superficie que vigila. La quinta SÍ tiene sujeto hoy y no la vigilaba nadie: F1 entregó el primitivo de actor (`$libs/actor` + el registro WeakMap privado del motor) y su invariante — que SOLO el motor acuña — no estaba protegida por nada. El token es una marca de compilación sin constructor en runtime: un forjado resuelve a null, pero un `as ActorToken` TIPA, y un contexto de actor construido a mano en el canon es exactamente la suplantación que el eje prohíbe (agent.md §5). Por eso D-AG.8 §2 dice literalmente que su defensa es el lint de agent-check, no el sistema de tipos. Dos reglas, sobre canon (uix · arts · libs · svrs · packs · web) excluyendo el arte agente: - `actor-forgery` — cast a ActorToken fuera de $agent - `actor-handbuilt` — `actor:` con valor literal (objeto/string/número) en vez de un token RECIBIDO; reenviar (`actor: opts.actor`) es la costura sancionada y calla. Los tests quedan exentos: ahí fabricar un forjado es precisamente lo que se prueba. Verificado en negativo, que un guard que nunca falla es teatro: inyectado un cast + un contexto a mano en `sema/signal.ts` → 2 hallazgos con fichero:línea y exit 1; revertido y de vuelta a limpio. `npm run agent:check` cableado junto a los demás guards del repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
528af6f72d |
docs(blocks): F1 CERRADA (8/8) · registro de sidebar y su review
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
59f20e2b1f |
uix(aura): el Status en dos líneas — cierra D1
La otra mitad de la dirección firmada: el anillo dice el estado como FORMA, pero la respuesta a «¿quién actúa?» es texto, y una palabra gris de 13px junto a un orbe vivo no la daba. Ahora el Status son dos renglones: Esperando tu revisión ← el estado, content-primary, peso medium la custodia es tuya ← qué significa para ti, secondary, un escalón menos Sin parte nueva: el Status ya existía y añadir un `Detail` habría sido abstracción prematura (y una pelea de layout — dos hermanos no apilan sin envoltorio). El soma renderiza las dos líneas por defecto y expone `detailText` en los snippet props, así que un consumidor que traiga sus children sigue mandando. La copia del detalle es FIJA por estado y localizada como la etiqueta (es/en): los contadores reales del run (turnos / actos) NO están en el puerto estructural, y ensancharlo para un subtítulo más bonito es una decisión, no un defecto. Queda dicho en el README por si algún día se firma. Tokens: `--aura-status-color` pasa a `content-primary` (era secondary: el peso informativo estaba en el sitio equivocado), + `-weight`, `-gap` y `-detail-color`. Verificado en Chrome real, claro y oscuro, con un run en `reviewing`: peso 500, primary sobre secondary, y las dos líneas escalando con `data-size`. Tests 478, eidos-lint 0 invalid / 0 class-hooks, morfo:vocabulary 0 errores, check en los 73 ajenos preexistentes. Con esto D1 queda cerrada entera (anillo + jerarquía). Handoff al día. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
e10eed98cc |
uix(aura): la superficie visible del agente — anillo de custodia, orbe-contorno y desenlaces expresados
Rediseño dirigido por el usuario sobre un banco de mockups con el orbe REAL
corriendo dentro. Seis frentes, todos con maquinaria existente:
ANILLO DE CUSTODIA (parte nueva `Aura.Ring`, morfo+soma+eidos)
El estado se lee como FORMA y no solo como tinte: raíl punteado en reposo,
arco que respira al ofrecerse, segmentos = pasos del plan (laten), dos arcos
enfrentados y QUIETOS esperando tu revisión (la quietud lo separa de acting),
arco que gira actuando, anillo cerrado + pulso saliente cuando te necesita.
Envuelve al Indicator (es su marco de referencia, no un hermano posicionado a
mano). El movimiento continuo son loops REGISTRADOS (data-animation-style),
nunca @keyframes de receta (R-4.5) — vienen con su puerta de reduced-motion,
donde el dash sigue distinguiendo el estado. El attr va en los hijos del SVG,
jamás en la parte: motionAttrs() estampa además data-state, del morfo ahí.
EL ORBE ES UN CONTORNO
`thickness` en el efecto orb; el hueco es real (alfa propia) sobre cualquier
fondo. Se va la rama claro/oscuro y el parámetro backgroundColor: el shader
mezclaba con el fondo y derivaba el alfa del canal máximo, o sea pintaba un
disco OPACO del color de la superficie justo en el centro (en claro un círculo
relleno; en oscuro el azul del seed). Y la receta deja de pintar su disco en
cuanto monta el canvas (:has(canvas)) — solo sobrevive donde no hay render
vivo: SSR, tests, effect={false}, sin WebGL.
COLOR = TOKENS DE ROL, PINTADO Y NO ROTADO
colorA/colorB/colorDeep (solid / solid-hover / element) resueltos con
eidos.resolveToken y pasados como hex, que es el seam que el propio arte
documenta. El hue-delta anterior se medía en OKLCH y se aplicaba en YIQ: risk
salía VERDE junto a su propio anillo naranja.
ONION EN EL IDIOMA DEL ORBE
Prop `look="solid" | "luminous"` (defecto solid: nadie más se entera). En
luminous el sector no tiene relleno — filo de luz (pasada borrosa + nítida) y
etiqueta en el color del sector; la cuña sigue siendo área táctil. El trigger
con snippet propio va BARE: sin disco, sin sombra FAB y sin el salto del hover
(el orbe ES el trigger, no su contenido). Medio anillo bottom-center y radios
44/40. El halo respira (loop pulse) y en commit-select da UNA pasada de ping
pivotando en el centro real del menú — la firma genérica de commit anima
box-shadow, que sobre un path de SVG no hace nada.
DESENLACES EXPRESADOS (el hueco real: un fallo era indistinguible de un éxito)
Tres eventos terminales con intent INTRÍNSECO — delegate-return (fulfill) /
-aborted (sin intent: un decline es ausencia, no pérdida) / -failed (loss) —
en vez de un intent dinámico, que no tiene dónde vivir: TriggerOptions no
lleva intent y el fromProp del morfo ata a un prop PÚBLICO, no a estado de
máquina. Puerto `runs?` opcional en AuraAgentSource porque activeRun ya es
null al cerrar (§0: sin él, anuncio genérico). Primeras firmas de la familia
delegate en el registro; la de loss es MOVIMIENTO (return-recoil: retirada +
descenso), no tinte — no estrena ningún hue.
MAPA SEMÁNTICO DE COLOR (demo)
Un hue = un significado en toda la superficie: gris=sin agencia ·
naranja=tu revisión · morado=él actúa · rojo=escalated (exclusivo) ·
teal=tu sí. El anillo de autoridad reusa los colores de la custodia con el
MISMO sentido (Review=risk porque vivirás en reviewing; Auto=primary porque
actúa) y los declines pasan a neutral — canon: el intent de un cancel es
`absent`. Además el anillo en reposo DELEGA (las tres autoridades abren el
run) y se cierra por transición, no siempre que no hay run.
Dos guardas del framework corrigieron el diseño por el camino:
- BK-FRAME-NO-INTENT rechazó dar intent a una familia de marco sin
justificación escrita (excepción A-1): queda el intentRationale — el motor
no emite nada y no hay evento evaluable que enmarcar, así que el retorno
consolidado es el ÚNICO sitio expresivo del desenlace.
- fallbackTarget gana sobre el target del morfo (contrato de TriggerOptions):
el sello caía en el provider. Los terminales pasan el Ring cuando existe.
Verificado en Chrome real (ventana delante: en segundo plano el navegador
congela rAF y ResizeObserver y las medidas mienten): seis estados en claro y
oscuro, y un error de transporte REAL apuntando a un puerto muerto →
delegate-return-failed · loss · return-recoil sobre el Ring · región
«Agente: falló — control devuelto».
Tests 478 (morfo 114 · soma/aura 11, +5 casos de desenlace · eidos 353),
eidos-lint 0 invalid / 0 class-hooks nuevos, morfo:vocabulary limpio,
check en los 73 errores ajenos preexistentes.
Pendiente (handoff actualizado): la jerarquía tipográfica del Status (D1
llevaba dos líneas y solo se hizo el anillo) · el pulso de commit-select se
corta si el consumidor cierra el anillo al elegir (necesita retención tipo
Presence) · D5 la superficie de composición del encargo, decisión abierta.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
e28df1817f |
docs(blocks): registro F1.7 fase morfo+soma en el plan
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
ef6bd13be3 |
uix(nav-tree): `disabled` por nodo — destino no disponible
Decisión del usuario. Un nodo deshabilitado conserva su fila (sigue siendo parte del mapa) pero pierde el `href`: no hay nada que activar con clic, Enter ni «abrir en pestaña nueva». Un `pointer-events: none` de CSS solo habría tapado el ratón. - morfo: la parte `link` gana `data-disabled` (propRef) y `aria-disabled` (literal `true` bajo `prop-truthy: disabled`). - soma: `disabled` solo aplica con `href` (un grupo sin destino lo ignora); el toggle del grupo NUNCA se deshabilita — mostrar/ocultar es control de vista, no destino. - eidos: fila en `--color-content-disabled`, sin puntero y sin hover. - demo: «Agent» va deshabilitado con badge «Soon» + filas de API y a11y. Verificado en navegador real: `<a>` sin href, `aria-disabled="true"`, `data-disabled`, color 0.79 frente a 0.61 de una fila normal, clic sin efecto, fuera del orden de tabulación (44 focusables en vez de 45), badge dentro del control. `component:audit` PASS · eidos-lint 28 morfo-backed / 0 invalid · `vitest src/uix/eidos` 353/353 · svelte-check 0 errores míos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
a7e629f9ed |
uix(nav-tree): F1.8 CERRADA · demo + navegador + review adversarial
Cierra el árbol de navegación data-driven (E-1) de F1: demo canónica de 9
pestañas con el mapa real de docs (43 nodos, 3 niveles), verificación en
navegador real y review adversarial (5 dimensiones × 3 verificadores
escépticos; 22 hallazgos brutos, 10 confirmados) con todos los confirmados
arreglados.
Arreglos del review
- sema: la parte `group` —target de los eventos emerge— se registraba SIN
`ref`, así que `runtime.trigger` lanzaba `SomaRuntimeTargetError` en
silencio y el pack no sonaba nunca (cero `data-event-*` en el grupo frente
a los de collapsible). El provider posee ahora el ref del `<ul>`.
- eidos: en una fila navegable el chevron resolvía `inline-size: 100%` como
flex-basis y ocupaba media fila (101 de 231 px en «Soma»), robándole clics
al enlace. Toggle compacto con suelo de diana de 24 px (WCAG 2.5.8).
- soma: una clave duplicada podía volver cíclico `parentByKey` y colgar la
pestaña dentro de `trailKeys` (deriva en render) → clave sufijada + aviso
del logger + guarda de ciclo en el paseo.
- soma: el colapso es CONTEXTUAL (recuerda el `activeKey` bajo el que se
hizo): cerrar la sección que lees se respeta, pero caduca al navegar
DENTRO del grupo, para que la página actual nunca quede sin fila visible.
Sigue siendo query pura, sin `$effect` que escriba estado.
- soma: `child` recibe también `children` (el árbol renderizado); antes
dejaba el landmark vacío, porque un árbol data-driven no lo puede
reautorar el consumidor.
- morfo + langs: el nombre accesible del chevron se declara en el contrato y
se localiza («Alternar sección {label}»); ya no duplica el del enlace.
- eidos: RTL completo — el glyph espeja solo (bordes lógicos), lo que no
espeja es el giro, así que bajo `[dir='rtl']` las dos rotaciones se
intercambian. El Gap «dirección del chevron en RTL» queda RESUELTO.
- demo: paridad de snippet con los controles vivos; fuera el token fantasma
`--nav-tree-rail-width` del docblock del recipe.
badge en v1 (decisión del usuario, delegada)
Está en el suelo de paridad del dossier §P5 (los 6 refs lo llevan). Se
resuelve con SNIPPET, no con recursión a nivel de eidos: el morfo declara la
parte `badge`, soma renderiza el snippet recibido (sin él, el valor crudo —
sigue siendo headless) y el wrapper de eidos pasa el `Badge` canónico. Va
DENTRO del control de la fila, así su texto entra en el nombre accesible
(«TSC, New, enlace»). `disabled` se descarta en v1 (fuera del suelo, y un
enlace de navegación deshabilitado es semánticamente dudoso); ambos quedan
registrados en la tabla de Gaps.
Verificado: `component:audit` PASS · eidos-lint 26 morfo-backed / 0 invalid ·
`svelte-check` 0 errores en estos archivos · `vitest src/uix/eidos` 353/353 ·
navegador real (Playwright): trail auto-expandido, sema estampando en el
grupo, teclado nativo, foco visible, claro y oscuro, RTL, 375 px sin
desbordes, 0 errores de consola.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
549c5e5abd |
docs(agent): D-AG.12 pendiente de firma — el contrato como referencia
PLAN §5: la decisión editorial planteada con el usuario (2026-07-22) queda firmable al retomar — (a) elevar agent.md a especificación publicable («el contrato de delegación») con agent-check como suite de conformance y el checklist de amenazas como anexo; (b) nombrar las dos reclamaciones de frontera que F4/F2 ya materializan: contexto por atención y delegación como transacción; (c) posición honesta declarada (acts secuenciales v1, cliente-first, generalidad pendiente del 2º/3º consumidor). continue-agente: punto 0 del orden de trabajo → firmar D-AG.12. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
e835163103 |
uix(nav-tree): F1.8 WIP · data-driven docs nav tree (soma+sema+eidos)
Complete component, green on all static gates (audit PASS, eidos-lint 20/0, svelte-check 0, contracts clean for its parts). NOT tree-view: APG Disclosure Navigation (<nav> landmark + native links + disclosure groups), data-driven (E-1) — the app passes `nodes` + `activeHref`, the provider resolves the active node and auto-expands its ancestor trail. - morfo: nav/list/item/trigger/link/group; emerge-expand/collapse events - soma: NavTreeProvider (shared state, pure isExpanded query) + per-node NavTreeItemProvider (menubar pattern, recursive render) - sema pack: soft emerge on group disclosure (mirrors collapsible) - eidos: rail + per-depth indent recipe; own bespoke rows (not composed Link), Badge deferred to a Gap; aria-current="page" from data-active Remaining before F1.8 closes: demo + browser verify + adversarial review. Handoff: docs/process/CONTINUE-nav-tree.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
1cc8a87722 |
docs(agent): continue-agente — handoff para la próxima sesión
Estado al cierre (F0/F1/F3/F4a cerradas + tabla de commits), verificación rápida al retomar, siguiente trabajo en orden (F4b chat → F2 gated → flecos), y la disciplina operativa de la rama compartida + gotchas de entorno (Ollama/OpenWebUI, pane, Chrome MCP, index:0 del stream). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
0ab40cdcee |
uix(agnt): Aura al centro de un OnionMenu — afordancias radiales por estado
La composición que pidió el usuario: el orb es el trigger central de un OnionMenu placement="center" y las afordancias de custodia aparecen como sectores contextuales — reviewing→Authorize/Reject, escalated→Approve/Deny, activo→Stop — sin fila de botones. El anillo se abre SOLO mientras la custodia espera a un humano, con re-aserción (un cierre externo sin resolver re-abre: el efecto lee onionOpen como dependencia); por click en el centro mientras actúa; se pliega al devolver el control. App-land por doctrina (agent.md §7): el framework da estados + afordancias (Aura) y componentes (OnionMenu); el app da forma a la superficie de review. Patrón documentado en el README de aura (§Patrón). E2E verificado en Chrome real contra qwen3-coder: la escalada real por doc.clear abre el anillo con el orb rojo al centro → Deny en el sector → returned(aborted, user-cancel) + «Agente: terminó — control devuelto» + documento intacto. check 0 propios · smoke agnt PASS. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
595040b73b |
feat(agnt): Aura como superficie de presencia de la demo con modelo real
La respuesta a «¿está pensando?» no se improvisa — es Aura, el componente
del eje construido para ello. La sección real de la página agnt bootea un
uix standalone mínimo (createActiveUix + Soma + ActiveEidos + eidos css):
legítimo porque un app compone ambos tiers, y la demo ES el app.
- Motor llama → createActiveAgent (mismas opciones bus+journal); activeRun
reactivo satisface AuraAgentSource; stream vía .engine.onEvent
- <Aura {agent}> con Indicator (orb $scene) + Status + Region + Cancel;
authorize/escalation quedan como afordancias app-level (doctrina §7)
- Verificado sobre el run real de qwen3-coder: «Inactivo» → «Propone un
plan» → announcement «Agente: terminó — control devuelto» en la Region,
doc mutado, answer en es; Cancel = Button disabled-en-idle; consola 0
check 0 propios · agent 30/30 · smoke agnt PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
447a87239c |
feat(agent): adaptador openai-chat real + carril de iniciativa del bus
El bus como eje del agente a nivel de app, cerrado en tres direcciones:
observar (agent.*), reaccionar (orca) e INICIAR — hecho de dominio → acción
orca → App.agent.start({initiative:'system'}) con clamp auto→review por
construcción. Nunca command-events. Sección doctrinal + ejemplo en la página.
Adaptador real `$agent/adapters/openai-chat` (fuera del barrel, D-AG.1c):
dialecto OpenAI chat-completions (Ollama/llama.cpp/LM Studio/proxy), SSE →
protocolo v1, sanitización bidireccional de capability ids con puntos, y
re-pairing de tool_calls al reproducir el transcript (memoria por callId).
Fix cazado en vivo: Ollama reutiliza index:0 para todas las calls del
stream — una call nueva se detecta por id distinto, jamás por index (los
args concatenados producían invalid-args en motor + 400 en el replay).
Demo viva en /active/docs/agnt contra qwen3-coder:30b real: capacidades
doc.* tipadas (sium), read snapshot-por-turno, streaming, escalada
irreversible. Ciclo completo verificado en navegador: 3 acts, 2 turnos,
doc mutado, respuesta en es, rastro entero en bus (correlationId=runId).
agent 30/30 · smoke agnt PASS · check 0 propios.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
fa71890564 |
fix(agent): conformidad bus/orca — payload del bus sin contenido de usuario
Auditoría punto-a-punto contra los README de bus y orca (12/13 conforme).
La no-conformidad real: `goal` viajaba en AgentRunBusPayload, contra la
higiene documentada de ambos (bus: «pasa correlationId y que el suscriptor
resuelva el contexto sensible del módulo»; orca: «no unnecessary private
data — la acción lo resuelve del módulo al ejecutar la acción»).
- AgentRunBusPayload = SOLO metadata (runId/initiative/autonomy/state/
outcome/reason/acts/turns); el suscriptor resuelve vía App.agent.run(runId)
- spine test prueba el patrón: 'goal' in payload === false + resolución
desde el módulo con el orca REAL
- página agnt: nota de higiene + recomendación configureEvent(
'agent.run.state', { queuePolicy: ORCA_QUEUE_REPLACE_QUEUED }) para el
evento frecuente (doctrina de colas de orca)
- PLAN-agent F4a: acta de la auditoría de conformidad
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
803b588ba5 |
feat(agent): F4a · marco de integración app — bus/orca/página del arte + fixes de auditoría
Auditoría del track (encargo): divergencias firmadas-sin-implementar corregidas y el marco de integración INDEPENDIENTE del componente — el agente como servicio del app, no como demo de un componente. Fixes de decisiones firmadas (con tests): - C3/D-AG.7: la iniciativa autónoma (system/scheduled) clampa auto→review — un run que el usuario no pidió jamás se auto-autoriza. - D-AG.5: presupuesto de contexto (maxContextBytes) con FIFO-trim byte-based (el goal sobrevive; resumen semántico diferido) + log del recorte. - F4c: tope por-arg (maxArgBytes) → invalid-args tipado. - D-AG.6d: schema Standard-Schema del resultado (`result?`); un mismatch vuelve como recoverable para auto-corrección y no cuenta como act. Integración app (patrón session EXACTO): - El arte posee el vocabulario `agent.*` (consts) + bus-helpers tipados que publican con bus INYECTADO (type-only $libs/bus): run.opened/state/ escalated/closed + act.applied, con source='agent' y correlationId=runId — la costura causal ligera (una delegación correlaciona de punta a punta). - defineActiveAgent cablea core.bus (junto a timers/logger). - Reacciones vía orca APP-LAND (el invariante intacto): probado con EngineOrca REAL reaccionando a agent.run.closed en integration.test. - Página del arte /active/docs/agnt (la convención que faltaba): sección Delegation en nav; artículo + playground VIVO con los 4 motores puros reales (bus log en vivo, journal WAL, contador orca, kill switch, compuertas deterministas) — cero componentes, integración pura de app. Gates: agent 26/26 · smoke agnt PASS · check 0 propios · verificado en navegador (pane + Chrome real): ciclo completo, orca archiva runs, kill switch reactivo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
2803d5dddc |
docs(blocks): registro F1.6 anchor-nav · F1 = 6/8
Adversarial-review outcome (fixes + documented v1 limits) and the two piggybacked sticky type-fixes recorded; scoreboard corrected (prose F1.5 had also landed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
e187ab6d72 |
docs(agent): F3 cerrada · doctrina «The review surface» — split framework/app
Cierra los dos flecos de F3 tras la corrección del usuario (la review-card con diff era anclaje en dev-tools, sin sentido a nivel framework): - agent.md §7 gana «The review surface»: el FRAMEWORK posee los estados del ciclo expresados perceptualmente (reviewing/escalated con afordancias authorize/reject/cancel — Aura ya las da) + la semántica de «propuesto por otro actor» + los anuncios atribuidos; el APP posee el CONTENIDO de lo que se revisa, en su propio dominio (un documento enseña sus bloques propuestos, un calendario sus eventos pendientes). Una tarjeta-diff estilo git es legítima en una aplicación concreta; jamás canon. - §6 fatiga de aprobación enmendada en el mismo sentido (el cambio concreto en el dominio del app, nunca prosa). - PLAN: F3 CERRADA — review resuelta como doctrina sin componente nuevo; `allowedFamilies` del primer componente actuado reubicada a F2 (su hogar natural es el piloto). Siguiente: F4 por la vía del chat. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
2c175c5d95 |
feat(aura): fases 7–8 · README eidos + component:audit PASS — Aura completa (0–8)
Cierra el primer componente del eje agéntico de punta a punta (las 9 fases de la ruta). `component:audit` PASS. - README eidos con comparativa (5 refs adyacentes — thinking-indicators, CopilotKit activity, Vercel useChat.status, presencia colaborativa Figma/Docs, assistant-ui) reconociendo el paisaje escaso: nadie tiene una semántica perceptiva de la delegación con a11y (informe §8.3). Decisiones + Gaps con disposición. - Fixes del audit: opacity literal `0.5` → `var(--opacity-50)` (R-4.2); excepción R-1.5 documentada (único focusable = Cancel, que compone Button); `apg: 'none — …'` en el morfo (A-1.4). Gates: component:audit PASS · morfo:vocabulary limpio · eidos-lint aura 0 inválidos · recipe-contract verde. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
6be7195f0f |
feat(agent): eje agéntico — motor $agent (F1) + Aura + promoción uix.scene
Materializa el eje ortogonal agéntico del ecosistema: la 8ª familia semántica
`delegate` («¿quién actúa ahora?») deja de estar sin materializar. El agente es
OTRO ACTOR (LLM, macro, regla, workflow) que actúa por la MISMA API pública del
provider; la ruta de llamada no se bifurca, la concreción semántica depende del
actor.
F0 · Doctrina
- docs/architecture/agent.md — la doctrina permanente (capítulo comparativo de
referencias + bibliografía de seguridad, máquina estados=verbos, contrato de
participación, fila §0, a11y, amenazas).
- docs/process/{PLAN,TRIAGE,INFORME}-agent — plan de ejecución con todas las
decisiones firmadas (D-AG.1–11 + ⚖️1/2/3), triage de 4 revisores externos, e
informe autocontenido para revisión externa.
F1 · Motor ($libs/actor + arts/agent, 24º arte)
- EngineAgent puro (sin DOM/runes, portable a servidor): máquina D-AG.4
(suggest/review/auto · escalated con reason+timeout · returned outcome-tipado
· kill switch · autorización journaled aunque sea auto), tool-loop D-AG.5
(acts secuenciales, fallos→verbos, unknown-capability acotado, idempotencia
por callId, presupuestos acts/turns/wall-clock vía puerto de timers), techo de
autonomía por origen no confiable (F8b).
- ActiveAgent (sesión reactiva, contrato ActiveEngine) · protocolo v1 espejo
AG-UI (5 categorías + dirección tipada + reservas) · ScriptedAgentTransport
determinista (adapters/ fuera del barrel) · journal WAL + puerto de trazas
OTel · emisor sium→JSON Schema.
- Acuñación del actor (⚖️2/F6b): ActorToken opaco en $libs/actor (hoja bajo
orca/agent), registro privado WeakMap — los forjados resuelven a null;
costura `actor?` en TriggerOptions→SemanticSignal (runtime copia verbatim;
sema no resuelve). defineActiveAgent (service-factory app-level, timers del
core — cero setTimeout a pelo).
F3 · Aura — primer componente del eje (ruta 9 fases 0–6)
- El materializador canónico de `delegate` (reservado en scene §F6): morfo con
los eventos del ciclo (offer/escalate-untilAction/return + sustain-processing
stateBound) — PRIMER morfo del ecosistema que emite familia delegate; provider
soma que observa un puerto estructural (sin importar $agent — degradación
total); orb eidos = aurora $scene modulada por estado (§F6) con fallback CSS
= render de reduced-motion; live region única atribuida (WCAG 4.1.3); cancel
compone Button (asChild). Demo v2 sobre el MOTOR REAL con compuertas
deterministas. Orb-size derivado de la primitiva Avatar (32/40/48).
D4 · Promoción uix.scene (Aura llegó)
- defineEngineScene + superficie ActiveUix/ActiveEidos/contracts; el orb prefiere
el motor compartido (presupuesto de escenas global) con fallback por-superficie.
Gates: arts/agent 18/18 · aura 6/6 · arts:check 24 · eidos battery + recipe
30/30 + eidos-lint aura 0 inválidos · morfo:vocabulary + esquemas · smoke aura
PASS · verificado en navegador (ciclo completo + estampa delegate en DOM +
aurora WebGL pintando). Los tokens de recipe base.ts + CSS generado ya entraron
en HEAD vía una sesión concurrente.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
955c6a18b3 |
docs(blocks): registro F1.5 prose · 5/8 F1
|
3 months ago |
|
|
11ba4b906b |
docs(blocks): registro · review sticky + fix writing-mode · F1.1 CERRADO
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
c6964496b4 |
docs(blocks): registro F1.1 sticky · 4/8 F1 hechas
Registra sticky (
|
3 months ago |
|
|
9124570e69 |
uix(callout): F1.4 · admonicion inline (morfo+eidos) al suelo del dossier
Tercera pieza F1 del plan blocks (alcance E-2, dossier §P3). Banner = tira de anuncio de pagina; Callout = el aside del documento (split deliberado). - morfo: 4 partes (provider role=note / icon / title / content) + texts con TITULOS DEFAULT LOCALIZADOS por intent (note/tip/warning/caution — patron GitHub de label visible: la semantica nunca viaja solo en color/icono); 0 eventos justificados (dismissible DIFERIDO a pasada soma+sema por la regla de admision — dismiss ES un evento real) - el hueco IMPORTANT resuelto con el modelo Radix, sin 5o enum: `intent` (neutral|affirm|risk|threat — mapea NOTE/TIP/WARNING/CAUTION) + `color` override SOLO bajo neutral (doctrina §4: intent evaluativo gana); IMPORTANT = intent neutral + color + titulo propio (preset en la demo) - pintura sobre la maquinaria C6/THM-2 (patron badge): forwarders por color + slots `_palette-track/text/solid` → el generador emite la cascada de 8 roles Y el forward presence-guarded al shared layer — 33 escalas y colores custom con CERO CSS extra - a11y: role=note NOMBRADO via aria-labelledby → Title SOLO mientras esta montado (registro reactivo por context local); escalacion tipada role=status|alert|none (el role=alert estatico de shadcn = bug de referencia que NO copiamos); Title NO es heading (protege el outline que escaneara anchor-nav); icono decorativo = mapa doctrinal IntentIcon - fix cazado en navegador: el `+=` del registro leia el estado dentro del tracking del $effect del hijo → effect_update_depth silencioso (contador a -997, attr nunca estampado) — untrack() en register/cleanup; leccion registrada en memoria (incidente 2 de la clase) - recipe: grid con acento logico border-inline-start (RTL-correcto), nesting tolerado (Docusaurus); demo v2 9 tabs con preset IMPORTANT + PalettePicker showIntent=false; README completo Verificacion: component:audit PASS 0E/0W · eidos-lint 8 morfo-backed/0 invalid · guards 37/37 · svelte-check 76E/51W = baseline exacto · navegador: «Nota»/«Atencion» localizados · risk=ambar hue 45-60 · IMPORTANT=plum hue 326 resuelto por shared layer · labelledby=titleId · cero errores de consola. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
bf940c9a4a |
uix(result): F1.3 · estado terminal de flujo/pagina (morfo+eidos) al suelo del dossier
Segunda pieza F1 del plan blocks (alcance E-2 = suelo de paridad, dossier
§P3). Comparte el esqueleto de empty-state a proposito: EmptyState describe
AUSENCIA de datos, Result reporta un RESULTADO — un lenguaje de layout, dos
contratos (duplicacion consciente registrada en el README; revisable al 3er
consumidor).
- morfo: 6 partes display (provider/media/title/description/actions/extra;
extra SIN archetype — parte genuinamente propia), scope ['eidos'],
0 eventos justificados (el resultado ya OCURRIO antes de renderizar)
- status: enum de 7 = paridad AntD CON `warning` (decision firme del
dossier) y HTTP renombrados semanticos (forbidden/not-found/server-error,
nunca '404' stringly); default 'info'; data-status = attr eidos-only
- media default: compone el mapa doctrinal IntentIcon (success→fulfill ·
error→threat · warning→risk) + Info de catalogo; HTTP = codigo mono
grande NEUTRO aria-hidden (situaciones, no fallos — AntD jamas pinta 404
de rojo); children reemplazan el default entero (context local eidos-only
con getter reactivo)
- Title default h2 (vs h3 de empty-state — Result suele SER la pagina);
Actions con label→role=group; Extra alineado a inicio (detalle que lee)
- recipe: glifo display 3× xl bundle; tokens publicos
gap/actions-gap/measures + {status}-color como forwarders de rol
retintables; sin eje size (paridad AntD, gap diferido)
- demo v2 9 tabs con copy por status + entrada nav (Status) + README
(Comparativa · Decisiones · Passive justification · Gaps con disposicion)
Verificacion: component:audit PASS 0E/0W · eidos-lint 6 morfo-backed + 5
eidos-only sancionados · recipe/api/visual-attrs 37/37 · morfo:check verde
(los 7 fallos listados son deuda foranea preexistente) · svelte-check
76E/51W = baseline exacto · navegador: success=fulfill verde 84px ·
error=threat rojo · not-found=«404» mono neutro, copy conmutando, cero
errores de consola.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
f19e91b985 |
uix(empty-state): F1.2 · componente base display (morfo+eidos) al suelo del dossier
Primera pieza F1 del plan blocks (PLAN-blocks.md; alcance E-2 = suelo de paridad, dossier §P3). Ruta de 9 fases completa: - morfo: 5 partes display (provider/media/title/description/actions), scope ['eidos'], 0 eventos con justificacion pasiva (patron renderEmptyState de las refs headless), Title role:'heading', texts.label - langs: components.empty-state.label (es/en) — el indice tambien recoge la retirada foranea del import de words (inseparable por staging de archivo; coherente con la migracion palabras ya enviada; words.ts sigue en su arbol) - eidos: compound EmptyState + Media(kind icon|media, placa 2x glifo) + Title(level 2-6, default h3 — modelo Atlaskit, tamano visual desacoplado) + Description(measure 45ch) + Actions(label -> role=group +aria-label, buttonGroupLabel); recipe sobre el bundle --size-* (titulo un paso discreto arriba; sm=in-collection, lg=hero); tokens publicos minimos (gap/actions-gap/media-bg/media-fg/media-radius/description-measure) - demo v2 9 tabs (harness: SystemAxes/MotionPanel/SemaPanel; snippet con paridad; escena in-collection via Card) + entrada nav (grupo Status) - README: Baseline · Comparativa (shadcn/Chakra/Atlaskit/AntD/Polaris) · Decisiones · Passive justification · Gaps con disposicion Verificacion: component:audit PASS · eidos-lint 5 morfo-backed + 4 eidos-only sancionados · morfo:check + morfo:vocabulary verdes · recipe-css-contract/api-contract/visual-attrs 37/37 · svelte-check 76E/51W = baseline exacto (cero regresion) · navegador claro Y oscuro por estilos computados (titulo 18->24px, placa 40->64px, chips vivos, cero errores de consola). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
647db398ee |
blocks(plan): enmiendas E-1..E-5 firmadas — F1=8 (+nav-tree), F2=14, paridad=v1
Firmas del usuario (2026-07-21) tras el dossier de referencia: - E-1: componente canonico nav-tree (F1.8, data-driven — precedente Menubar) resuelve la colision sidebar-app vs arbol-docs/B-5; fiche nueva con fase 0 obligada contra nuestro tree-view; docs-shell compone NavTree. - E-2: suelo de paridad del dossier = alcance v1 (regla en intro F1). - E-3: F2 pasa de 10 a 14 (banner · team · contact · content-section); fiches nuevas + galeria actualizada (verificada en navegador: 28 badges). - E-4: distribucion registry/llms.txt/MCP → iniciativa propia (next-features §9; ese archivo sigue fuera del commit por diff foraneo). - E-5: ⌘K = listener app-land documentado (nota en F4.1). Doctrina: promotion path de architecture/blocks.md actualizado a 8. Verificacion: docs:check 0/0 (512). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
aff42fee0f |
docs(blocks): dossier de referencia — 6 pistas, suelos de paridad + enmiendas E-1..E-5
Encargo del usuario (2026-07-21): estudio de referencia para "estar al menos a la par y cuanto menos superarlo". 6 agentes de investigación web en paralelo sobre fuentes oficiales vivas (varias verificadas a nivel de código fuente: sidebar.tsx del registry shadcn, styles.js de tailwind-typography, sources de Mantine/Starlight/Docusaurus/Ark). - docs/process/RESEARCH-blocks-references.md — el dossier: P1 catálogos de marketing (conteos+variantes) · P2 aplicación (ProTable/ProLayout, dashboard-01, Tremor 303, Clerk/Supabase) · P3 F1 ligeros (APIs a nivel de prop; scroll-state(stuck) como vocabulario de plataforma; role=alert de shadcn = bug a no copiar) · P4 prose+sidebar (not-prose/:where()+donut; shadcn 23 partes) · P5 docs shells (Fumadocs benchmark; colision F1.7 vs nav-tree/B-5; ruta svelte2tsx para props TS) · P6 ecosistema Svelte (shadcn-svelte 58 blocks solo-app; hueco "sistema integrado" VACIO) + sintesis: 5 conclusiones, enmiendas E-1..E-5 (presentadas, firmas pendientes), 10 angulos de superacion. - PLAN-blocks.md — regla nueva §4 (toda fase 0 contrasta contra el dossier), puntero de colision en F1.7, registro. Verificacion: docs:check 0/0 (512 docs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
0697596046 |
blocks(tier): F0 · infraestructura del tier (doctrina + $blocks + guard + galería)
Tier nuevo aprobado 2026-07-21 (D-BLK firmadas; D-BLK.1 enmendada: vive en src/uix/blocks/). Plan de ejecución completo en docs/process/PLAN-blocks.md. - docs/architecture/blocks.md — doctrina E1 (regla de admisión canon-vs-block, contrato B-1..B-11, promotion path); espejo de packs.md - alias $blocks → src/uix/blocks (vite + svelte.config + tabla CLAUDE.md) - src/uix/blocks/README.md — mapa del tier + template de README de block (B-9) - scripts/blocks-check.ts + npm run blocks:check — guard mecánico del contrato B con self-test de detectores (fixtures inline; 5532 archivos de canon/arts/libs/packs escaneados para dirección de imports) - web/routes/blocks/ — galería índice del catálogo planificado + layout de bootstrap propio (+layout@.svelte, espejo mínimo del de /uix sin packs sema) Verificación: docs:check 0/0 (511) · svelte-check 76E/51W = baseline exacto · blocks:check verde · galería comprobada en navegador (a11y-tree + estilos computados en light y dark; captura de píxel bloqueada por panel suspendido). Fuera del commit: fila E1 en docs/README.md y §8 en docs/next-features.md (diff foráneo de otra sesión sin separar — ver registro del plan). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
d59b8af9aa |
uix(chat): v2 · emoji-picker (picker completo) + escaparate rico del bloque
Nuevo componente emoji-picker y rediseño del escaparate de mensajeria. emoji-picker (ruta 9 fases): - Compone Popover (open/close/foco/portal) + Command (busqueda + grid + nav de teclado + a11y combobox/listbox, su "grid mode" documentado) + dos ToggleGroup (categorias + tono de piel). Delegated: sin eventos propios (D.1); el grid y las celdas doble-registran Command.List/Item, conservando la a11y pero con contrato visual propio (gana especificidad con selectores de 2 niveles, sin tocar attrs [data-command-*] ajenos — eidos-lint limpio). - Datos: $libs/emoji, dataset vendorizado de emojibase (MIT) horneado por scripts/generate-emoji-data.ts (precedente lucide: JSON crudo en static/ + script generador). ~1906 emoji con nombre CLDR + keywords, 316 con tono de piel single-person. Grid acotado (categoria activa o resultados de busqueda), sin virtualizacion (refinamiento v2). Helpers puros + test (12/12). - morfo delegated (7 partes + header/footer de layout); soma (root + trigger + content + grid + option + preview, provider-test 4/4); eidos (panel empaquetado, receta con tokens --emoji-picker-*); langs es/en; demo 5 tabs (excepcion delegated documentada); READMEs dobles. Escaparate del bloque (web/routes/uix/demos/chat) — rehecho rico y correcto: - Avatares por-autor con color solido (Avatar del ecosistema): antes gris neutro indefinido, ahora teal/ambar/verde/indigo/primary bien contrastados. - Dos columnas: chat-list (sidebar con badges + typing-en-lista) + sala. - Conversacion rica: separador de dia, run agrupado, reaccion, reply citado, recibos de lectura, typing con avatar, y el emoji-picker integrado en el composer (inserta en el draft). - Solape de burbujas (transitorio, estimateSize=48 con mensajes ~90-126px) mitigado subiendo el estimate a 76. Auditoria de tamanos/espacios: recipes del bloque limpios (todo con tokens --space-*/--size-*/--color-*); unico literal (punto tono-capable) tokenizado. Verificacion: check baseline 76 (0 nuevos) · component:audit emoji-picker PASS · eidos-lint invalid=0 · recipe-contract 30/30 · morfo:vocabulary 0 · emoji lib 12/12 · provider-test 4/4 · Playwright PASS (busqueda 'rocket'->rocket+ astronautas, click->onSelect+cierra, teclado, tono oscuro 👋->👋🏿, picker abre en el composer). Capturas claro miradas. next-features §7 marca emoji-picker SHIPPED. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
73411f1440 |
docs(color): amplía el cierre de Stage 2 — RFC §15 + README + stub
Documenta el resultado (el solver de contraste era innecesario: el morph HEREDA el contraste de donantes §40-compliant) en los docs de diseño/código: - docs/rfcs/rfc-color-engine.md: §15 nueva (resolución Stage 2 con las 3 bancas de evidencia + decisiones D1–D6), anotación de fases §11 (Phase 0 = tipos diferidos D5; Phase 3 = base→seeds NO se hace, D2), footer + §14. - src/arts/color/README.md: CONTRAST_PAIRS en la API + nota "contraste heredado, no resuelto" con puntero a RFC §15 y reference §40. - src/uix/eidos/COLOR_ENGINE_RFC.md (stub): deja de sobreafirmar que el tipo ColorScaleSeed existe (está diferido, D5) + puntero a §15. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
5aa8090bad |
color: contraste Stage 2 — contrato §40 como datos + guard CI; solver descartado
La ejecución refutó la premisa del plan: el morph HEREDA el contraste del texto (steps 11/12 = curva-L del donante verbatim; ~invariante al croma bajo gamut-mapping), así que toda escala desde donantes §40-compliant cumple por construcción. Medido en 3 bancos (base, leave-one-out, 45 semillas OOD): 0 fallos del gate duro text-strong·12, min WCAG 9.7:1. El solver de luminancia no tenía nada que resolver → descartado por especulativo. D2 = base verbatim (sin migración base→seeds). - $color: CONTRAST_PAIRS (arts/color/contrast-contract.ts) — tabla §40 como datos compartidos: floor duro text-strong·12, banda text·11 (tope relacional, sin nº mágico), border·7 exento - scripts/contrast-audit.ts: muere la PAIRS pre-veredicto (4.5 duro contra §40), consume CONTRAST_PAIRS + banco de regresión morph-generado - eidos/lib/contrast-invariant.test.ts: guard de CI (4 tests) que bloquea la herencia - docs: reference.md §40, next-features.md §1, changelog.md §45, plan (OUTCOME) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
f9889b0b18 |
uix(chat): v2 · chat-list — panel de conversaciones (compone Listbox)
Componente nuevo del bloque chat v2: el panel de lista de salas/DMs. Compone el Listbox del ecosistema (doble registro id/ref compartido): selección única + roving-tabindex + typeahead + role=option vienen de Listbox; chat-list aporta la disposición de fila (avatar · título/preview · meta) y el estado visual data-unread (negrita + Badge compuesto). - morfo: expression 'delegated', sin eventos propios (D.1 — el actor es el Listbox compuesto); parts provider/item(data-unread)/avatar/title/preview/meta. - soma: ChatListProvider crea ListboxProvider dentro (value string <-> string[]); ChatListItemProvider per-instance (unread = boolean crudo); 4 clases de contenido explicitas. - eidos: rejilla avatar | (titulo/preview) | meta, avatar y meta abarcan las dos filas; truncado; unread -> titulo en negrita. No neutraliza el arquetipo item (la conversacion ES una opcion seleccionable). Sin @keyframes; ejes logicos. - demo: 5 salas, seleccion limpia unread, typing-en-lista (compone ChatTyping), Badge de no-leidos; tabs live/system/api/morfo/a11y. - READMEs dobles (eidos con Passive justification, delegated); next-features 7 marca chat-list SHIPPED. Verificacion: check baseline 76 (0 nuevos) · component:audit PASS · eidos-lint invalid=0 · recipe-contract 30/30 · morfo:vocabulary 0 · Playwright PASS (role=listbox, 5 salas, aria-selected, unread=2, badges=2, typing-en-lista, click + teclado seleccionan). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
44a016538c |
docs(color): plan verificado de Contraste Stage 2 (generador by-construction)
Plan de ejecucion para sesion aparte, VERIFICADO adversarialmente (workflow de
7 agentes contra codigo y docs) antes de escribirse — corrige 5 afirmaciones
de la respuesta que lo origino:
- "por delante de Radix (hex sRGB)": FALSO — el propio RFC §14 registra Radix
con APCA y P3 ("Radix style"); la posicion del repo es "on par"; nuestra
paleta enviada es sRGB-equivalente (oklch = siblings de hex).
- "el solver satisface la tabla §40": el UNICO floor duro ratificado es
text-strong·12 ≥ 4.5; text·11 quedo tier blando (decision D1); solid·9 esta
anclado exacto a la semilla; el script de auditoria aun codifica la tabla
PRE-veredicto (consumirla contradiria los veredictos → F0 = tabla como datos).
- "los tipos ya existen en parte": ColorScaleSeed/Source son solo prosa del
RFC; config-seeds imposibles hoy (solo applyColorScheme roles-only +
generatePalette full-33 como bancos).
- "792 hex en base.ts": exacto en total pero en DOS ficheros (288 base.ts +
504 color-scales.ts); 4 escalas ya autoradas desde semillas offline.
- "nada downstream cambia": nombres si (contract.ts), pero hay pins de VALOR
disenados para dispararse (hex literales, flip-set de polaridad,
generated/base.css byte-exacto) + persistencia rechaza version ≠ 1.
El plan: F0 tabla ratificada como datos + harness sobre output generado ·
F1 solver (biseccion contra sRGB gamut-mapeado, salida hex, desviacion minima
del donante) · F2 validacion en bancos de semilla + navegador · F3 (gated)
migracion base→seeds con re-ratificacion de pins y pase visual. 6 decisiones
de usuario ABIERTAS al frente (target text·11, semantica base+ΔE, modo
on-solid, colocacion/alcance, tipos Fase 0, normalizacion de la tabla).
next-features §1 enlaza el plan. (El hunk ajeno de chat-list en next-features
queda fuera del commit — danza clean-desde-HEAD.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
d3f10b89cf |
docs(chat): design-record §v1→v2 status — remates de v2 shipped + frentes restantes
Actualiza el handoff en el design-record del bloque: v1 completo (incl. onMessageSeen), los 3 remates de v2 shipped (typing avatars, read-by, jump-to-message highlight con su decisión de visual-puro-sin-sema y el gotcha del boolean en attrs de presencia), y los frentes v2 restantes (chat-list, emoji-picker, threads, menciones, rangos bidireccionales) por valor/independencia. docs:check 0 errores. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
8fe9d1faaa |
uix(chat): v2 · jump-to-message highlight en chat-message
Tercer y último remate de v2 (batch elegido por el usuario). chat-message gana el prop `emphasized` → attr `data-emphasized`: al saltar a una cita (reply.onJump → scrollToIndex) la app enciende `emphasized` ~1.4s y la fila objetivo hace un flash suave que se desvanece. VISUAL PURO — sin evento de sema (desvía a propósito del signal-emphasize -target del plan): las apps de referencia hacen un flash SILENCIOSO; un signal que pitara por defecto sería molesto. Cumple 2-de-3 (soma escribe el attr, eidos lo lee). El pulso = toggle de dos estados + transition (cero @keyframes, R-4.5); reduced-motion = instantáneo. Morfo attr + soma prop/provider (devuelve el booleano al resolver, no '') + eidos recipe (wash color-mix 14% de toda la fila) + demo componente (botón flash) + escaparate (reply → jump → emphasize). next-features §7 marca los 3 remates shipped. Verificado (Playwright): flash on → bg tintado → auto-clear a 1.4s; escaparate intacto. audit PASS, eidos-lint invalid=0, recipe-contract 30/30, check en baseline (76). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
e838e7107b |
uix(chat): v2 · read-by list — parte ReadBy en chat-message
Segundo remate de v2. chat-message gana la parte opcional `ReadBy`: una fila de avatares "visto por N" que la app compone (AvatarGroup), típica de mensajes propios; el emisor la alimenta con los acuses recolectados vía el onMessageSeen (v1). DECORATIVA (aria-hidden): el indicador Status ya transmite "read" a AT; las caras son realce visual. Morfo part + soma provider/wrapper + eidos wrapper/recipe (fila de avatares muted, ejes lógicos in/out) + demo con toggle. next-features §7 marca read-by y typing-avatars como shipped. Verificado (Playwright): la fila aparece con 3 avatares + "Visto por 3", aria-hidden, en la columna del cuerpo. component:audit PASS, eidos-lint invalid=0, recipe-contract 30/30, check en baseline (76). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
b2f0a7f2bf |
docs(theming): ratifica la doctrina de contraste tonal — Stage 1 (paridad)
Cierra Stage 1 de la iniciativa next-features §1 con los veredictos del usuario: - reference.md §40 (doctrina standing): contrato de contraste por pares de slots. Texto = dos tiers (text·11 secundario ≈APCA 60 / text-strong·12 AA garantizado). Bordes = dos tiers WCAG 1.4.11 (decorativo exento: accent·7, subtle·4/default·6, reposo-sobre-fondo · portador 3:1: solid·9 lo cumple, el resto con señal redundante). Foco = eje de config (primitives.focusRing + color.focus, un solo `outline` por §32); default suave, endurecer = valores por config, no código. - changelog.md §44: el chronicle datado (drift medido + veredictos + la herramienta scripts/contrast-audit.ts). - next-features.md §1: Stage 1 marcado DONE; Stage 2 (generador by-construction) sigue abierto, gated en la migración base→seeds. Sin cambios de código (el hallazgo del foco es una decisión de valores-por- defecto vía config; defaults mantenidos por decisión del usuario). El script de auditoría (commiteado antes) queda como herramienta de medición. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
c5b268cbff |
docs(next-features): registra la reversión de THM-2 (#6) por la jaula del color
La entrada #6 (THM-2 rollout) decía que los controles semánticos (checkbox/ radio/stepper/select/file-upload) y `Avatar.Badge` quedaban role-restricted "por diseño". La iniciativa open-color-cage (2026-07-18/19) revirtió justo eso: `color` = sistema completo en TODOS los componentes. Se añade la nota de reversión con puntero al handoff; qr-code queda fuera por diseño. Sin cambios de código. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
82c91093d5 |
docs(chat): design record del bloque + README de $libs/chat
Documentación del bloque chat-* recién shippeado, siguiendo la convención
del corpus (por-componente = READMEs dobles; por-lib = README; doctrina de
bloque = design record en decisions).
- docs/decisions/design-chat-block.md: la doctrina cross-cutting que abarca
los 4 componentes — la tesis comparativa (5 fallos del sector = nuestras
oportunidades), la topología de composición (triple registro Feed +
VirtualList anclado, Textarea, FileUpload, Icon lucide), el anclaje
(sticky monótono, pin contra DOM real), la doctrina visual del rediseño
de referencia y los 2 fixes de framework que destapó. Indexado en
decisions.md (sección "Component families — design records").
- src/libs/chat/README.md: los helpers puros (groupIntoRuns ventana 8min,
aggregateTypers, límites de día) — convención de README por lib.
docs:check 0 errores (503 docs). Los READMEs por componente y next-features
§7 ya iban en el commit del bloque (
|
3 months ago |
|
|
4c4878f139 |
uix(chat): bloque de mensajería chat-* v1 (log · message · composer · typing)
Familia chat-* completa, componiendo el ecosistema (Feed + VirtualList anclado, Textarea, FileUpload, Avatar, Popover, Icon). Transporte-agnóstica: el modelo de datos es de la app, los componentes reciben props + snippets. - chat-log: Feed + VirtualList(anchor:'end') en triple registro; day separators, unread divider, filas de sistema (Feed.Article), pill "N nuevos" + notifyIncoming (announce a live-region), to-latest distance-aware. - chat-message: raíz Feed.Article; runs ($libs/chat), ticks de entrega, reply embebido, reacciones (chip pressed + tapback panel), acciones hover. - chat-composer: Textarea (doble registro) + FileUpload; teclado Enter/Shift+Enter/Esc/ArrowUp; typing saliente debounced (uix.timers); barra reply/edit. - chat-typing: sustain-streaming (visual-only, loop del sistema); aggregateTypers 1/2/3+ con plantillas plurales. - $libs/chat: groupIntoRuns (ventana 8 min estilo Discord) + aggregateTypers. - VirtualList: extensión anchor:'end' (followOutput, prepend por clave estable, sticky monótono, onAtEndChange) — sin scroller paralelo. Diseño de referencia (WhatsApp/Telegram, pase lado-a-lado): burbujas suaves (out = primary-element + texto normal; in = surface card + sombra) sobre lienzo muted del log, meta dentro de la burbuja, tapback bar horizontal, iconos lucide del ecosistema (nada de SVG a mano). Contrato de tamaños: size="md" = 16px canónico. Fixes de framework (afectaban más allá de chat): - EngineLangs.t() ahora pela el prefijo '#?': los idlangrefs imperativos (pagination/file-upload/chronos/chat) caían al fallback EN en locale es. Fix parseLangRef ?? parsePathFallback + test de regresión (132/132). - virtual-list commit-set-resize con channels:[]: es bookkeeping de ResizeObserver, no gesto → dejaba de emitir beep/vibrate pre-interacción (interventions de navigator.vibrate / AudioContext). Escaparate messenger en /uix/demos/chat (bot de eco con uix.timers; variante $connection señalada). Gaps v2 registrados en next-features §7. Pase: component:audit 4×PASS · eidos-lint invalid=0 · recipe-contract 29/29 · Playwright escaparate PASS end-to-end · consola limpia · npm run check en baseline (76, cero errores nuevos). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
f0de4faf75 |
docs(color): handoff de cierre definitivo de la jaula del color
Actualiza el handoff y el changelog §43 al estado FINAL de la iniciativa (cerrada, cuarta sesión): - open-color-cage-2026-07.md: añade las 2 fugas transitivas cerradas (card-group-item · s-text) + el guard runtime, el fix del bug de Card/Avatar (`b93cc6c5c`), la lista completa de commits (sesiones 3–4), y una sección «Follow-ups» con lo menor que queda (override docs-chrome sobre `<Code>`, ringColor roles-only, límites de los 2 guards, comentarios históricos) + nota del estado del working tree (WIP de chat/palabras sin commitear, ajeno). - changelog.md §43: el bug de Card/Avatar pasa de «flageado, NO arreglado» a ARREGLADO con el resumen del fix (migración a resolveComponentColor + compose del seed + canales ring/badge separados intactos). Sin cambios de código. La iniciativa queda CERRADA sin huecos abiertos (qr-code excluido por diseño). Contract 30/30. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |