ansimax 1.2.7 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,156 @@
3
3
  All notable changes to **ansimax** are documented in this file.
4
4
  This project follows [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [1.3.0] — Phase 4 progress: Panels + JSON pretty-print
7
+
8
+ Minor release adding **split layout primitives** and **JSON pretty-printing**.
9
+ Two new top-level modules, zero breaking changes — every 1.2.x program runs
10
+ identically.
11
+
12
+ ### Added — `panels` module (split layouts)
13
+
14
+ Two composition primitives for combining already-rendered blocks:
15
+
16
+ - **`panels.vsplit(blocks, opts)`** — joins blocks side-by-side (columns).
17
+ ANSI-aware width measurement, variable height handling, alignment, gap,
18
+ fixed-width mode.
19
+
20
+ - **`panels.hsplit(blocks, opts)`** — stacks blocks vertically (rows).
21
+ Width alignment, vertical gap.
22
+
23
+ ```js
24
+ import { panels, ascii } from 'ansimax';
25
+
26
+ // Two columns side-by-side
27
+ console.log(panels.vsplit([
28
+ ascii.box('Left side', { borderStyle: 'rounded' }),
29
+ ascii.box('Right side', { borderStyle: 'rounded' }),
30
+ ], { gap: 2 }));
31
+
32
+ // Three rows stacked vertically
33
+ console.log(panels.hsplit([
34
+ '── Header ──',
35
+ ascii.box('Body content'),
36
+ '── Footer ──',
37
+ ], { align: 'center' }));
38
+
39
+ // Nested — sidebar + main in an app shell
40
+ const sidebar = ascii.box('Sidebar', { width: 20 });
41
+ const main = ascii.box('Main', { width: 40 });
42
+
43
+ console.log(panels.hsplit([
44
+ '── Application ──',
45
+ panels.vsplit([sidebar, main], { gap: 2 }),
46
+ ]));
47
+ ```
48
+
49
+ **Both functions:**
50
+ - Preserve ANSI escapes from input blocks
51
+ - Handle multi-line blocks of variable height
52
+ - Coerce invalid inputs (`gap: -5` → `0`, empty arrays → `''`)
53
+ - Compose freely with each other (panels-in-panels)
54
+
55
+ Three alignment modes (`'start'` / `'center'` / `'end'`) for both axes.
56
+
57
+ ### Added — `json` module (pretty-printer)
58
+
59
+ Color-coded JSON pretty-printer for terminal display:
60
+
61
+ ```js
62
+ import { json } from 'ansimax';
63
+
64
+ // Basic — colored output
65
+ console.log(json.pretty({
66
+ name: 'ansimax',
67
+ version: '1.3.0',
68
+ features: ['colors', 'gradients', 'panels'],
69
+ stats: { tests: 2000, coverage: 0.98 },
70
+ }));
71
+
72
+ // With depth limit — deep nesting collapses to {...}
73
+ console.log(json.pretty(deeplyNested, { maxDepth: 2 }));
74
+
75
+ // Limit array display — huge arrays show "... (N more)"
76
+ console.log(json.pretty(bigArray, { maxItems: 10 }));
77
+
78
+ // Monochrome for log files
79
+ console.log(json.pretty(data, { colors: false }));
80
+
81
+ // Handles circular refs gracefully
82
+ const obj = { name: 'foo' };
83
+ obj.self = obj;
84
+ console.log(json.pretty(obj)); // → { "name": "foo", "self": [Circular] }
85
+ ```
86
+
87
+ **Features:**
88
+ - Color-coded by type: cyan (keys), green (strings), yellow (numbers), magenta (booleans), gray (null/undefined)
89
+ - Circular reference detection
90
+ - Depth limit with `{...}` / `[...]` collapse markers
91
+ - Array length limit with `... (N more)` marker
92
+ - String length limit with `...` truncation
93
+ - BigInt, function, symbol rendering
94
+ - ANSI auto-disabled in `NO_COLOR` / non-TTY environments
95
+ - Configurable indent (default `2`)
96
+
97
+ ### Roadmap impact — Phase 4 progress
98
+
99
+ Phase 4 (Terminal UI primitives) advances from 8/15 → **10/15**:
100
+
101
+ - [x] Panels (split layouts: hsplit, vsplit) ← **v1.3.0**
102
+ - [x] JSON/YAML pretty-printing (with depth limit + collapse) ← **v1.3.0**
103
+
104
+ Still pending in Phase 4: Layouts (flexbox-style), Grid system, Markdown
105
+ rendering, Syntax highlighting, Logging integration. These come in later
106
+ 1.3.x / 1.4.x releases.
107
+
108
+ ### Notes
109
+
110
+ - 2 new test files: `panels.test.ts` (~25 tests), `json.test.ts` (~30 tests)
111
+ - No runtime dependencies — still zero
112
+ - No breaking API changes — pure additions
113
+ - Drop-in replacement for `1.2.8`
114
+
115
+ ---
116
+
117
+ ## [1.2.8] — Documentation polish
118
+
119
+ Patch release improving JSDoc and IntelliSense coverage across previously
120
+ under-documented modules. No code changes — pure documentation upgrade.
121
+
122
+ ### Improved — JSDoc with runnable examples
123
+
124
+ The following functions now have full JSDoc with `@example` blocks visible
125
+ in editor IntelliSense (VS Code, IntelliJ, etc.):
126
+
127
+ **`components/` (previously 0 examples → now 4):**
128
+ - `components.table` — 3 examples (basic, custom borders, colored cells)
129
+ - `components.badge` — 3 examples (basic, custom colors, inline composition)
130
+ - `components.status` — 3 examples (basic, multiline, custom icons)
131
+ - `components.timeline` — 3 examples (basic, done/pending, custom symbols)
132
+
133
+ **`loaders/` (previously 0 examples → now 2):**
134
+ - `loader.spin` — 3 examples (basic, custom type/color, try/finally pattern)
135
+ - `loader.tasks` — 4 examples (serial, subtasks, parallel mode, error handling)
136
+
137
+ **`themes/` (previously 0 examples → now 4):**
138
+ - `themes` object — 4 examples (switching, registering, subscribing, fallback)
139
+
140
+ **`animations/` (previously 1 example → now 6):**
141
+ - `animate.typewriter` — 4 examples (basic, colored, abortable, reduced-motion)
142
+ - `animate.fadeIn` — 3 examples (basic, custom timing, abortable)
143
+
144
+ **`ascii/`:**
145
+ - `ascii.box` — 4 examples (basic, multiline, fixed-width, with color)
146
+
147
+ ### Notes
148
+
149
+ - No new tests required — pure documentation changes
150
+ - No runtime dependencies — still zero
151
+ - No API changes — drop-in replacement for `1.2.7`
152
+ - IntelliSense quality dramatically improved for new users
153
+
154
+ ---
155
+
6
156
  ## [1.2.7] — Bug fixes + robustness
7
157
 
8
158
  Patch release focused on edge case handling, better error messages, and
package/README.es.md CHANGED
@@ -7,12 +7,13 @@
7
7
  _Colores • Gradientes • Animaciones • ASCII Art • Pixel Art • Árboles • Componentes • Temas_
8
8
 
9
9
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square)](LICENSE)
10
- [![npm](https://img.shields.io/badge/npm-v1.2.7-cb3837.svg?style=flat-square)](https://www.npmjs.com/package/ansimax)
10
+ [![npm](https://img.shields.io/badge/npm-v1.3.0-cb3837.svg?style=flat-square)](https://www.npmjs.com/package/ansimax)
11
11
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6.svg?style=flat-square)](tsconfig.json)
12
12
  [![Coverage](https://img.shields.io/badge/coverage-98%25-brightgreen.svg?style=flat-square)](#testing)
13
- [![Tests](https://img.shields.io/badge/tests-1900%2B%20passing-brightgreen.svg?style=flat-square)](#testing)
13
+ [![Tests](https://img.shields.io/badge/tests-2000%2B%20passing-brightgreen.svg?style=flat-square)](#testing)
14
14
  [![Zero deps](https://img.shields.io/badge/dependencies-0-brightgreen.svg?style=flat-square)](#)
15
- [![Bundle](https://img.shields.io/badge/bundle-%3C100kb-brightgreen.svg?style=flat-square)](#)
15
+ [![Node](https://img.shields.io/badge/Node-%3E%3D18-43853d.svg?style=flat-square)](#requirements)
16
+ [![ESM%20%2B%20CJS](https://img.shields.io/badge/ESM%20%2B%20CJS-dual-blueviolet.svg?style=flat-square)](#)
16
17
 
17
18
  [English](README.md) · **Español**
18
19
 
@@ -79,30 +80,40 @@ stop('Build completado', true);
79
80
 
80
81
  ## 🆚 Comparación con el ecosistema Node.js
81
82
 
82
- Ansimax reemplaza un stack de dependencias de librerías populares de Node.js con un solo paquete coherente y tipado:
83
+ Ansimax reemplaza un stack de librerías populares de Node.js con **un solo paquete coherente, tipado y de cero dependencias**:
83
84
 
84
85
  | Característica | chalk | gradient-string | ora | cli-progress | figlet | boxen | inquirer | cli-table3 | **Ansimax** |
85
86
  |---|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
86
87
  | Colores básicos + 256 | ✅ | — | — | — | — | — | — | — | ✅ |
87
88
  | Truecolor con fallback adaptativo | ✅ | ✅ | — | — | — | — | — | — | ✅ |
88
89
  | Gradientes multi-stop | — | ✅ | — | — | — | — | — | — | ✅ |
89
- | **Gradientes animados** | — | — | — | — | — | — | — | — | 🔜 |
90
+ | **Gradientes animados** | — | — | — | — | — | — | — | — | |
91
+ | **Curvas de easing (5 presets + custom)** | — | — | — | — | — | — | — | — | ✅ |
92
+ | **Gradientes cónicos (barrido radial)** | — | — | — | — | — | — | — | — | ✅ |
90
93
  | Banners ASCII | — | — | — | — | ✅ | — | — | — | ✅ |
94
+ | **Conversor Imagen → ASCII** | — | — | — | — | — | — | — | — | ✅ |
95
+ | **Parser figlet `.flf`** | — | — | — | — | ✅ (propio) | — | — | — | ✅ (250+ fuentes) |
91
96
  | Registro de fuentes personalizadas | — | — | — | — | parcial | — | — | — | ✅ |
92
- | Cajas con múltiples estilos | — | — | — | — | — | ✅ | — | — | ✅ |
97
+ | Cajas con múltiples estilos | — | — | — | — | — | ✅ | — | — | ✅ (6 estilos) |
93
98
  | Spinners (varios estilos) | — | — | ✅ | — | — | — | — | — | ✅ (11 estilos) |
94
99
  | Barras de progreso animadas | — | — | — | ✅ | — | — | — | — | ✅ |
95
100
  | **Tareas jerárquicas/paralelas** | — | — | — | — | — | — | — | — | ✅ |
96
101
  | Tablas (multi-línea, conscientes de ANSI) | — | — | — | — | — | — | — | ✅ | ✅ |
97
102
  | Menús interactivos + multi-select | — | — | — | — | — | — | ✅ | — | ✅ |
98
103
  | **Árboles con detección de ciclos** | — | — | — | — | — | — | — | — | ✅ |
104
+ | **Layouts divididos (vsplit/hsplit)** | — | — | — | — | — | — | — | — | ✅ (v1.3.0) |
105
+ | **Pretty-printer JSON coloreado** | — | — | — | — | — | — | — | — | ✅ (v1.3.0) |
99
106
  | **Pixel art + canvas + sprites** | — | — | — | — | — | — | — | — | ✅ |
100
107
  | **Sistema de temas + aislamiento por instancia** | — | — | — | — | — | — | — | — | ✅ |
101
108
  | `AbortSignal` en todas partes | — | — | parcial | — | — | — | parcial | — | ✅ |
102
- | Soporte de `NO_COLOR` | ✅ | parcial | parcial | — | — | — | — | — | ✅ |
103
- | TypeScript-first | parcial | parcial | | parcial | parcial | | parcial | parcial | ✅ |
104
- | Cero dependencias en runtime | | | | | | | | | ✅ |
105
- | **Tamaño total de instalación** | pequeño | pequeño | medio | medio | medio | pequeño | grande | medio | **< 100 KB** |
109
+ | Soporte `NO_COLOR` | ✅ | parcial | parcial | — | — | — | — | — | ✅ |
110
+ | Códigos de error estables (`ANSIMAX_*`) | | | | | | | | | ✅ |
111
+ | TypeScript-first (strict mode) | parcial | parcial | | parcial | parcial | | parcial | parcial | ✅ |
112
+ | **Cero dependencias en runtime** | | | | | | | | | |
113
+ | Export dual ESM + CJS | parcial | parcial | ✅ | ✅ | parcial | ✅ | parcial | parcial | ✅ |
114
+ | **Cobertura de tests** | ~95% | parcial | parcial | parcial | parcial | parcial | parcial | parcial | **~98% (2000+ tests)** |
115
+
116
+ > La comparación refleja lo que cada librería soporta oficialmente al momento de escribir esto. Algunas librerías pueden combinarse para acercarse al conjunto de features de ansimax, pero al costo de tamaño de bundle, bugs de version-skew, y APIs inconsistentes.
106
117
 
107
118
  ---
108
119
 
@@ -225,7 +236,7 @@ await animateGradient('¡Listo!', ['#50fa7b', '#bd93f9'], {
225
236
 
226
237
  ### Curvas de interpolación (v1.2.0)
227
238
 
228
- <img src="media/easing_curves.png" alt="Colors and gradients" />
239
+ <img src="media/easing_curves.png" alt="Vista previa de curvas de easing" />
229
240
 
230
241
  ```js
231
242
  import { gradient } from 'ansimax';
@@ -245,7 +256,7 @@ console.log(gradient('hola mundo', stops, { easing: (t) => t * t * t }));
245
256
 
246
257
  ### Gradientes cónicos (v1.2.0)
247
258
 
248
- <img src="media/conic_gradients.png" alt="Colors and gradients" />
259
+ <img src="media/conic_gradients.png" alt="Vista previa de gradientes cónicos" />
249
260
 
250
261
  ```js
251
262
  import { gradientRect } from 'ansimax';
@@ -434,7 +445,7 @@ console.log(components.table([
434
445
  ['loaders', color.green('● listo'), '100%'],
435
446
  ], { borderStyle: 'rounded' }));
436
447
 
437
- console.log(components.badge('VERSION', 'v1.2.7'));
448
+ console.log(components.badge('VERSION', 'v1.3.0'));
438
449
  console.log(components.badge('BUILD', 'passing'));
439
450
  ```
440
451
 
@@ -544,6 +555,61 @@ console.log('tenantB incluye custom?', tenantB.list().includes('custom'));
544
555
  // ↑ false — aislamiento total
545
556
  ```
546
557
 
558
+ ### Panels — Layouts divididos (v1.3.0)
559
+
560
+ ```js
561
+ import { panels, ascii } from 'ansimax';
562
+
563
+ // Columnas lado a lado
564
+ const left = ascii.box('Sidebar', { borderStyle: 'rounded' });
565
+ const right = ascii.box('Vista principal', { borderStyle: 'rounded' });
566
+
567
+ console.log(panels.vsplit([left, right], { gap: 2, align: 'center' }));
568
+
569
+ // Apilado vertical
570
+ console.log(panels.hsplit([
571
+ '── Aplicación ──',
572
+ ascii.box('Contenido'),
573
+ '── Pie ──',
574
+ ], { gap: 1, align: 'center' }));
575
+
576
+ // Anidado — sidebar + main dentro de un shell de aplicación
577
+ console.log(panels.hsplit([
578
+ '── Mi App ──',
579
+ panels.vsplit([
580
+ ascii.box('Sidebar', { width: 20 }),
581
+ ascii.box('Main', { width: 40 }),
582
+ ], { gap: 2 }),
583
+ '── Fin ──',
584
+ ]));
585
+ ```
586
+
587
+ ### JSON Pretty-print (v1.3.0)
588
+
589
+ ```js
590
+ import { json } from 'ansimax';
591
+
592
+ // Pretty-print coloreado y consciente de profundidad
593
+ console.log(json.pretty({
594
+ name: 'ansimax',
595
+ version: '1.3.0',
596
+ features: ['colors', 'gradients', 'panels'],
597
+ stats: { tests: 2000, coverage: 0.98 },
598
+ active: true,
599
+ }));
600
+
601
+ // Límite de profundidad — colapsa objetos profundos a {...}
602
+ console.log(json.pretty(deeplyNested, { maxDepth: 2 }));
603
+
604
+ // Límite de items — arrays grandes muestran "... (N more)"
605
+ console.log(json.pretty(largeArray, { maxItems: 10 }));
606
+
607
+ // Referencias circulares manejadas con gracia
608
+ const obj = { name: 'foo' };
609
+ obj.self = obj;
610
+ console.log(json.pretty(obj)); // → "self": [Circular]
611
+ ```
612
+
547
613
  ---
548
614
 
549
615
  ## 📚 Ejemplos
@@ -621,6 +687,102 @@ await withConfig({ animationSpeed: 'fast' }, async () => {
621
687
 
622
688
  ---
623
689
 
690
+ ## ⚠️ Códigos de error
691
+
692
+ Varias funciones de ansimax lanzan `Error` / `TypeError` / `RangeError` para inputs inválidos.
693
+ Hacer `catch` por código de error es la forma **estable y recomendada** para manejarlos programáticamente — el texto del mensaje puede cambiar, pero los valores `.code` están garantizados como semver-estables.
694
+
695
+ ```js
696
+ import { themes, ascii, parseFiglet } from 'ansimax';
697
+
698
+ try {
699
+ themes.use('tema-inexistente');
700
+ } catch (e) {
701
+ if (e.code === 'ANSIMAX_UNKNOWN_THEME') {
702
+ themes.use('dracula'); // fallback
703
+ } else {
704
+ throw e; // re-lanzar errores inesperados
705
+ }
706
+ }
707
+ ```
708
+
709
+ ### Todos los códigos de error
710
+
711
+ | Código | Lanzado por | Tipo | Cuándo |
712
+ |---|---|---|---|
713
+ | `ANSIMAX_INVALID_THEME` | `themes.register` | `TypeError` | El valor del tema no es un objeto plano |
714
+ | `ANSIMAX_INVALID_THEME_NAME` | `themes.register` | `TypeError` | El tema tiene `name` vacío o ausente |
715
+ | `ANSIMAX_UNKNOWN_THEME` | `themes.use` | `RangeError` | El nombre del tema solicitado no está registrado |
716
+ | `ANSIMAX_INVALID_FONT_NAME` | `ascii.registerFont` | `TypeError` | Nombre de fuente vacío o no string |
717
+ | `ANSIMAX_RESERVED_FONT_NAME` | `ascii.registerFont` | `Error` | Sobrescribir fuente built-in sin `{ force: true }` |
718
+ | `ANSIMAX_INVALID_FIGLET_INPUT` | `parseFiglet` | `TypeError` | Contenido `.flf` vacío o no string |
719
+ | `ANSIMAX_INVALID_FIGLET_HEADER` | `parseFiglet` | `TypeError` | La primera línea no es un header FIGfont válido |
720
+ | `ANSIMAX_INVALID_FIGLET_HEIGHT` | `parseFiglet` | `TypeError` | El header declara altura cero o negativa |
721
+
722
+ ---
723
+
724
+ ## 🧩 Paquetes del ecosistema
725
+
726
+ El **ecosistema ansimax** se estructura en dos niveles — paquetes companion que extienden el core, y evoluciones independientes que apuntan a diferentes plataformas.
727
+
728
+ ### `@ansimax/*` — Paquetes companion
729
+
730
+ Paquetes con scope que extienden `ansimax` sin romper su promesa de cero dependencias. Cada uno se publica de forma independiente pero comparte la filosofía y nombrado de ansimax.
731
+
732
+ | Paquete | Estado | Descripción |
733
+ |---|:-:|---|
734
+ | `ansimax` | ✅ estable | Core de renderizado terminal. Cero dependencias. |
735
+ | `@ansimax/image` | 🟡 planeado | Cargador imagen-a-ASCII — PNG/JPEG/WebP desde archivo/buffer/URL |
736
+ | `@ansimax/cli` | 🟡 planeado | Binario standalone — `npx @ansimax/cli demo`, explorador de fuentes, conversor de imágenes |
737
+ | `@ansimax/fonts` | 🟡 planeado | 250+ fuentes figlet `.flf` pre-empacadas, listas para usar |
738
+ | `@ansimax/sprites` | 🔴 futuro | Librería curada de sprites (animales, iconos UI, diagramas técnicos) |
739
+ | `@ansimax/video` | 🔴 futuro | Extracción de frames de video → reproducción ASCII |
740
+ | `@ansimax/themes-extra` | 🔴 futuro | Pack de themes contribuidos por la comunidad |
741
+
742
+ **Cómo se conectan:**
743
+
744
+ ```
745
+ ┌─────────────────────────────┐
746
+ │ ansimax (cero deps) │ ← core, siempre lo instalas
747
+ │ • colors, ASCII, panels │
748
+ │ • types: PixelGrid, etc. │
749
+ └────────────┬────────────────┘
750
+ │ peer dependency
751
+ ┌────────────────────┼────────────────────┐
752
+ ▼ ▼ ▼
753
+ @ansimax/image @ansimax/cli @ansimax/fonts
754
+ (deps: jimp) (binario) (solo datos)
755
+ ```
756
+
757
+ Cada companion declara `"ansimax": "^X.Y.Z"` como `peerDependency` — coordinado por semver, nunca duplicado, nunca desincronizado.
758
+
759
+ ### `ansimax-*` — Evoluciones independientes
760
+
761
+ Proyectos standalone que se construyen **al lado de** ansimax para diferentes plataformas. No son companions — son identidades separadas con su propio scope y ciclo de release.
762
+
763
+ | Paquete | Estado | Descripción |
764
+ |---|:-:|---|
765
+ | `ansimax-native` | 🔴 futuro | **Reescritura Rust + TS** del hot path de renderizado. Performance nativa via napi-rs. Misma superficie de API que `ansimax`. |
766
+ | `ansimax-web` | 🔴 futuro | **Capa de renderizado para browser**. Conversión ANSI → HTML/CSS + renderizado a canvas. Para demos, sitios de docs, terminales web. |
767
+
768
+ **Sub-ecosistemas**: cada uno de estos puede tener sus propios sub-paquetes con scope (`@ansimax-native/image`, `@ansimax-web/canvas`, etc.) con el tiempo.
769
+
770
+ ### ¿Por qué dos convenciones de nombrado?
771
+
772
+ Convención de la industria usada por muchos ecosistemas maduros (Babel, Vue, Webpack, etc.):
773
+
774
+ - **`@scope/*`** = "misma familia del proyecto, release coordinado, mismo equipo"
775
+ - **`name-*`** = "inspirado en / trabaja junto con, identidad independiente"
776
+
777
+ Al usar ambos, ansimax señala:
778
+ - El **core** (`ansimax`) se mantiene pequeño, cero-deps, enfocado en renderizado terminal
779
+ - El **ecosistema** (`@ansimax/*`) crece a su alrededor como extensiones opt-in
780
+ - Las **evoluciones** (`ansimax-native`, `ansimax-web`) exploran diferentes plataformas sin comprometer el core
781
+
782
+ > 💡 **Próximamente**: cuando se publiquen `@ansimax/image` o paquetes similares, esta sección incluirá enlaces. ¿Quieres que uno de estos se construya antes? [Abre un issue](https://github.com/Brashkie/ansimax/issues) para votar.
783
+
784
+ ---
785
+
624
786
  ## 🛣️ Roadmap
625
787
 
626
788
  Ansimax se está construyendo hacia una **plataforma completa de renderizado de terminal** — una respuesta nativa de Node a lo que los desarrolladores de Python obtienen de `rich` + `textual` combinados, con mejoras específicas de Node donde importa.
@@ -672,12 +834,12 @@ El roadmap apunta intencionalmente — y busca superar — gaps que ni siquiera
672
834
  - [x] Layout de columnas (overflow truncate/wrap)
673
835
  - [x] Secciones (cabeceras con gradiente, ancho automático)
674
836
  - [x] Árboles (colapsables, max-depth, cycle-safe)
675
- - [ ] **Panels** (split layouts: hsplit, vsplit)
837
+ - [x] **Panels** split layouts: `hsplit`, `vsplit` con alineación + anidamiento (v1.3.0)
838
+ - [x] **Pretty-printing JSON/YAML** — coloreado, depth-limit, cycle-safe (v1.3.0)
676
839
  - [ ] **Layouts** (posicionamiento estilo flexbox)
677
840
  - [ ] **Sistema de grid** (spans column/row inspirados en CSS Grid)
678
841
  - [ ] **Renderizado de Markdown** (headings, listas, code blocks, tablas)
679
842
  - [ ] **Syntax highlighting** (gramáticas integradas)
680
- - [ ] **Pretty-printing JSON/YAML** (con límite de profundidad + collapse)
681
843
  - [ ] **Integración de logging** (drop-in para `console`/`pino`/`winston`)
682
844
 
683
845
  ### ✅ Fase 5 — Control de cursor y pantalla
@@ -792,16 +954,23 @@ El roadmap apunta intencionalmente — y busca superar — gaps que ni siquiera
792
954
  ## 🧪 Testing
793
955
 
794
956
  ```bash
795
- npm test # Correr todos los 1700+ tests
957
+ npm test # Correr todos los 2000+ tests
796
958
  npm run test:watch # Modo watch
797
959
  npm run test:coverage # Reporte de cobertura
798
960
  ```
799
961
 
800
- Targets de cobertura:
801
- - Statements: **98%**
802
- - Branches: **95%**
803
- - Functions: **99%**
804
- - Lines: **99%**
962
+ Cobertura (a v1.3.0):
963
+
964
+ | Métrica | Score |
965
+ |---|:-:|
966
+ | **Statements** | ~98% |
967
+ | **Branches** | ~95% |
968
+ | **Functions** | ~99% |
969
+ | **Lines** | ~99% |
970
+ | **Tests totales** | **2,000+** |
971
+ | **Test suites** | 18 |
972
+ | **Matrix CI** | Node 18, 20, 22, latest |
973
+ | **Plataformas probadas** | Linux, macOS, Windows |
805
974
 
806
975
  ---
807
976
 
@@ -837,6 +1006,45 @@ ansimax/
837
1006
 
838
1007
  ## 📝 Changelog
839
1008
 
1009
+ ### v1.3.0 — Avance Fase 4: Panels + JSON pretty-print
1010
+
1011
+ Release minor que añade dos nuevos módulos top-level — split layouts y pretty-print de JSON:
1012
+
1013
+ - 🪟 **Módulo `panels`** — `vsplit` (columnas) + `hsplit` (filas) con consciencia ANSI, alineación (`start`/`center`/`end`), gap, modo ancho fijo, anidamiento
1014
+ - 🎨 **Módulo `json`** — pretty-printer coloreado con límite de profundidad, límite de items, truncamiento de strings, detección de referencias circulares
1015
+ - 🛣️ **Fase 4 del roadmap**: 8/15 → **10/15** completo
1016
+
1017
+ ```js
1018
+ import { panels, json, ascii } from 'ansimax';
1019
+
1020
+ // Columnas lado a lado
1021
+ console.log(panels.vsplit([
1022
+ ascii.box('Sidebar', { width: 20 }),
1023
+ ascii.box('Main', { width: 40 }),
1024
+ ], { gap: 2 }));
1025
+
1026
+ // Pretty-print JSON
1027
+ console.log(json.pretty({ name: 'app', tests: 2000 }, { maxDepth: 3 }));
1028
+ ```
1029
+
1030
+ Drop-in replacement para `1.2.8`. Dos módulos nuevos, cero breaking changes.
1031
+
1032
+ ### v1.2.8 — Pulido de documentación
1033
+
1034
+ Release patch con cobertura JSDoc + IntelliSense masivamente mejorada:
1035
+
1036
+ - 📝 **Módulo `components`** — `table`, `badge`, `status`, `timeline` ahora tienen JSDoc completo con ejemplos ejecutables
1037
+ - 📝 **Módulo `loaders`** — `loader.spin` y `loader.tasks` ahora muestran patrones de uso en IntelliSense
1038
+ - 📝 **Módulo `themes`** — JSDoc completo con ejemplos de cambio, registro y suscripción
1039
+ - 📝 **Módulo `animations`** — `animate.typewriter` y `animate.fadeIn` muestran cómo usar abort signals, reduced-motion, colores custom
1040
+ - 📝 **`ascii.box`** — 4 ejemplos (básico, multilínea, ancho fijo, con color)
1041
+ - 📖 **Sección Códigos de error** en README — los 8 códigos `ANSIMAX_*` documentados
1042
+
1043
+ Total: ~30 nuevos bloques `@example` visibles en tu editor. Cero cambios en código —
1044
+ tus programas existentes corren idéntico.
1045
+
1046
+ Drop-in replacement para `1.2.7`.
1047
+
840
1048
  ### v1.2.7 — Correcciones + robustez
841
1049
 
842
1050
  Release patch enfocado en manejo de edge cases y mejor DX: