ansimax 1.0.0 → 1.1.1
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 +274 -0
- package/LICENSE +201 -21
- package/README.es.md +752 -628
- package/README.md +493 -369
- package/dist/index.d.mts +1256 -336
- package/dist/index.d.ts +1256 -336
- package/dist/index.js +4417 -683
- package/dist/index.mjs +4319 -682
- package/examples/01-cli-installer.ts +96 -0
- package/examples/01-quick-smoke.ts +121 -0
- package/examples/02-colors-gradients.ts +108 -0
- package/examples/02-live-dashboard.ts +152 -0
- package/examples/03-ascii-banners.ts +81 -0
- package/examples/03-pixel-art-game.ts +170 -0
- package/examples/04-interactive-deploy.ts +163 -0
- package/examples/04-trees.ts +117 -0
- package/examples/05-components.ts +96 -0
- package/examples/05-tree-visualizations.ts +183 -0
- package/examples/06-everything-together.ts +466 -0
- package/examples/06-pixel-art.ts +116 -0
- package/examples/07-animations.ts +68 -0
- package/examples/08-loaders.ts +98 -0
- package/examples/09-themes.ts +90 -0
- package/examples/10-everything.ts +133 -0
- package/examples/all-in-one.cjs +210 -0
- package/examples/all-in-one.mjs +203 -0
- package/examples/animations.ts +172 -0
- package/examples/demo.js +213 -0
- package/examples/demo.ts +212 -0
- package/examples/loaders.ts +254 -0
- package/examples/showcase.ts +174 -0
- package/examples/trees-basic.ts +99 -0
- package/examples/tsconfig.json +18 -0
- package/examples/tsconfig.vscode.json +25 -0
- package/package.json +19 -7
package/README.md
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<img src="media/ansimax.png" alt="Ansimax" width="
|
|
4
|
-
|
|
5
|
-
# Ansimax
|
|
3
|
+
<img src="media/ansimax.png" alt="Ansimax logo" width="380"/>
|
|
6
4
|
|
|
7
5
|
### The ultimate CLI rendering library for Node.js
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
_Colors • Gradients • Animations • ASCII Art • Pixel Art • Trees • Components • Themes_
|
|
10
8
|
|
|
11
|
-
[](LICENSE)
|
|
10
|
+
[](https://www.npmjs.com/package/ansimax)
|
|
11
|
+
[](tsconfig.json)
|
|
12
|
+
[](#testing)
|
|
13
|
+
[](#testing)
|
|
16
14
|
[](#)
|
|
15
|
+
[](#)
|
|
17
16
|
|
|
18
17
|
**English** · [Español](README.es.md)
|
|
19
18
|
|
|
@@ -21,60 +20,89 @@ Colors • Gradients • Animations • ASCII Art • Pixel Art • Components
|
|
|
21
20
|
|
|
22
21
|
---
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
<div align="center">
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
### 🎬 Preview
|
|
26
|
+
|
|
27
|
+
<table>
|
|
28
|
+
<tr>
|
|
29
|
+
<td align="center">
|
|
30
|
+
<strong>Animations</strong><br/>
|
|
31
|
+
<img src="media/animations.gif" alt="Ansimax animations demo" width="420"/>
|
|
32
|
+
</td>
|
|
33
|
+
<td align="center">
|
|
34
|
+
<strong>Loaders</strong><br/>
|
|
35
|
+
<img src="media/loaders.gif" alt="Ansimax loaders demo" width="420"/>
|
|
36
|
+
</td>
|
|
37
|
+
</tr>
|
|
38
|
+
</table>
|
|
27
39
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
https://github.com/Brashkie/ansimax/raw/main/media/animations.mp4
|
|
40
|
+
</div>
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
---
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
## 🌟 What is Ansimax?
|
|
35
45
|
|
|
36
|
-
|
|
46
|
+
Ansimax is a **batteries-included rendering library** for building beautiful terminal UIs in Node.js. One package replaces a stack of 8+ dependencies — colors, gradients, ASCII art, spinners, progress bars, tables, menus, trees, themes, pixel art — combined into a single coherent TypeScript API with **zero runtime dependencies**.
|
|
37
47
|
|
|
38
|
-
|
|
48
|
+
```bash
|
|
49
|
+
npm install ansimax
|
|
50
|
+
```
|
|
39
51
|
|
|
40
|
-
|
|
52
|
+
```ts
|
|
53
|
+
import { color, gradient, ascii, loader } from 'ansimax';
|
|
41
54
|
|
|
42
|
-
|
|
55
|
+
console.log(ascii.banner('hello', {
|
|
56
|
+
colorFn: (t) => gradient(t, ['#ff79c6', '#bd93f9', '#8be9fd']),
|
|
57
|
+
}));
|
|
43
58
|
|
|
44
|
-
|
|
59
|
+
const stop = loader.spin('Building project', { color: '#bd93f9' });
|
|
60
|
+
await someAsyncWork();
|
|
61
|
+
stop('Build complete', true);
|
|
62
|
+
```
|
|
45
63
|
|
|
46
64
|
---
|
|
47
65
|
|
|
48
66
|
## 💡 Why Ansimax?
|
|
49
67
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
| Without Ansimax | With Ansimax |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Install 8+ packages: `chalk`, `gradient-string`, `figlet`, `ora`, `cli-progress`, `cli-table3`, `boxen`, `inquirer` | One install: `ansimax` |
|
|
71
|
+
| Mix incompatible APIs, different paradigms, conflicting types | Consistent functional API, single source of truth |
|
|
72
|
+
| No coherent theme system across packages | Built-in themes (Dracula, Nord, Matrix, Cyberpunk, +5) |
|
|
73
|
+
| Manual cursor cleanup, no crash safety | Reference-counted cursor + crash handlers built in |
|
|
74
|
+
| No `AbortSignal` support in most CLI libs | Every animation, loader, and prompt is abortable |
|
|
75
|
+
| Each lib brings its own runtime fallback logic | Unified `NO_COLOR` / `FORCE_COLOR` / TTY detection |
|
|
76
|
+
| No memory bounds on color caches | Bounded LRU caches everywhere (no leaks under load) |
|
|
56
77
|
|
|
57
78
|
---
|
|
58
79
|
|
|
59
|
-
## 🆚 Comparison
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
|
64
|
-
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
## 🆚 Comparison with the Node.js ecosystem
|
|
81
|
+
|
|
82
|
+
Ansimax replaces a dependency stack of popular Node.js libraries with one coherent, typed package:
|
|
83
|
+
|
|
84
|
+
| Feature | chalk | gradient-string | ora | cli-progress | figlet | boxen | inquirer | cli-table3 | **Ansimax** |
|
|
85
|
+
|---|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
|
86
|
+
| Basic + 256 colors | ✅ | — | — | — | — | — | — | — | ✅ |
|
|
87
|
+
| Truecolor with adaptive fallback | ✅ | ✅ | — | — | — | — | — | — | ✅ |
|
|
88
|
+
| Multi-stop gradients | — | ✅ | — | — | — | — | — | — | ✅ |
|
|
89
|
+
| **Animated gradients** | — | — | — | — | — | — | — | — | 🔜 |
|
|
90
|
+
| ASCII banners | — | — | — | — | ✅ | — | — | — | ✅ |
|
|
91
|
+
| Custom font registry | — | — | — | — | partial | — | — | — | ✅ |
|
|
92
|
+
| Boxes with multiple styles | — | — | — | — | — | ✅ | — | — | ✅ |
|
|
93
|
+
| Spinners (multiple styles) | — | — | ✅ | — | — | — | — | — | ✅ (11 styles) |
|
|
94
|
+
| Animated progress bars | — | — | — | ✅ | — | — | — | — | ✅ |
|
|
95
|
+
| **Hierarchical/parallel tasks** | — | — | — | — | — | — | — | — | ✅ |
|
|
96
|
+
| Tables (multi-line, ANSI-aware) | — | — | — | — | — | — | — | ✅ | ✅ |
|
|
97
|
+
| Interactive menus + multi-select | — | — | — | — | — | — | ✅ | — | ✅ |
|
|
98
|
+
| **Trees with cycle detection** | — | — | — | — | — | — | — | — | ✅ |
|
|
99
|
+
| **Pixel art + canvas + sprites** | — | — | — | — | — | — | — | — | ✅ |
|
|
100
|
+
| **Theme system + per-instance isolation** | — | — | — | — | — | — | — | — | ✅ |
|
|
101
|
+
| `AbortSignal` everywhere | — | — | partial | — | — | — | partial | — | ✅ |
|
|
102
|
+
| `NO_COLOR` env support | ✅ | partial | partial | — | — | — | — | — | ✅ |
|
|
103
|
+
| TypeScript-first | partial | partial | ✅ | partial | partial | ✅ | partial | partial | ✅ |
|
|
104
|
+
| Zero runtime dependencies | ✅ | — | — | — | — | — | — | — | ✅ |
|
|
105
|
+
| **Total install size** | small | small | medium | medium | medium | small | large | medium | **< 100 KB** |
|
|
78
106
|
|
|
79
107
|
---
|
|
80
108
|
|
|
@@ -82,441 +110,488 @@ Built for developers who want to ship CLIs that **feel** professional.
|
|
|
82
110
|
|
|
83
111
|
```bash
|
|
84
112
|
npm install ansimax
|
|
113
|
+
# or
|
|
114
|
+
pnpm add ansimax
|
|
115
|
+
# or
|
|
116
|
+
yarn add ansimax
|
|
85
117
|
```
|
|
86
118
|
|
|
87
|
-
|
|
88
|
-
yarn add ansimax # Yarn
|
|
89
|
-
pnpm add ansimax # PNPM
|
|
90
|
-
bun add ansimax # Bun
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Requires Node.js >= 18**
|
|
119
|
+
**Requirements:** Node.js ≥ 18. ESM and CJS both supported. Examples published with the package — see [`/examples`](./examples).
|
|
94
120
|
|
|
95
121
|
---
|
|
96
122
|
|
|
97
123
|
## ⚡ 30-second example
|
|
98
124
|
|
|
99
125
|
```ts
|
|
100
|
-
import { color } from 'ansimax';
|
|
126
|
+
import { color, gradient, loader, ascii } from 'ansimax';
|
|
101
127
|
|
|
102
|
-
console.log(
|
|
103
|
-
|
|
128
|
+
console.log(ascii.banner('deploy', {
|
|
129
|
+
colorFn: (t) => gradient(t, ['#ff6b6b', '#feca57', '#48dbfb']),
|
|
130
|
+
}));
|
|
104
131
|
|
|
105
|
-
|
|
132
|
+
const stop = loader.spin('Building project', { color: '#bd93f9' });
|
|
133
|
+
await someAsyncWork();
|
|
134
|
+
stop('Build complete', true); // ✓ + success color
|
|
135
|
+
|
|
136
|
+
console.log(color.green('✓') + ' Ready in ' + color.bold('1.4s'));
|
|
137
|
+
```
|
|
106
138
|
|
|
107
139
|
---
|
|
108
140
|
|
|
109
141
|
## 🚀 Quick Start
|
|
110
142
|
|
|
111
143
|
```ts
|
|
112
|
-
import {
|
|
113
|
-
|
|
114
|
-
// Colors with stacked styles (single ANSI reset, no nesting)
|
|
115
|
-
console.log(color.bold(color.cyan('Hello, terminal!')));
|
|
144
|
+
import { configure, color, themes, gradient } from 'ansimax';
|
|
116
145
|
|
|
117
|
-
//
|
|
118
|
-
|
|
146
|
+
// Global configuration
|
|
147
|
+
configure({ theme: 'dracula', animationSpeed: 'normal' });
|
|
119
148
|
|
|
120
|
-
//
|
|
121
|
-
|
|
149
|
+
// Basic styling
|
|
150
|
+
console.log(color.red('error'));
|
|
151
|
+
console.log(color.bold(color.cyan('important')));
|
|
122
152
|
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
153
|
+
// Multi-stop gradient
|
|
154
|
+
console.log(gradient('rainbow text', [
|
|
155
|
+
'#ff5555', '#ffaa00', '#ffff00',
|
|
156
|
+
'#00ff00', '#0099ff', '#cc44ff',
|
|
157
|
+
]));
|
|
127
158
|
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// Component table
|
|
132
|
-
console.log(components.table([
|
|
133
|
-
['Name', 'Status'],
|
|
134
|
-
['Build', '✓ ready'],
|
|
135
|
-
], { header: true, borderStyle: 'rounded' }));
|
|
159
|
+
// Switch theme — fires subscribers
|
|
160
|
+
themes.use('cyberpunk');
|
|
161
|
+
console.log(themes.primary('cyberpunk primary'));
|
|
136
162
|
```
|
|
137
163
|
|
|
138
164
|
---
|
|
139
165
|
|
|
140
166
|
## ✨ Features
|
|
141
167
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
168
|
+
- 🎨 **Colors** — Truecolor / 256 / basic with adaptive fallback. NO_COLOR / FORCE_COLOR / TTY detection
|
|
169
|
+
- 🌈 **Gradients** — Multi-stop linear, radial, diagonal, arbitrary-angle. Custom presets via `registerPreset`
|
|
170
|
+
- 🔠 **ASCII Art** — Banners (`big`/`small` fonts), boxes (6 styles), dividers, logos. Stream API + custom font registry
|
|
171
|
+
- 🖼️ **Pixel Art** — Sprites, alpha blending, dithered gradients, canvas with dirty-rect rendering, braille mode (2×4 sub-pixel)
|
|
172
|
+
- 🌳 **Trees** — Builder + plain-data API, 4 styles, per-node colors/icons, max-depth, cycle detection, walk/find/map/filter algorithms
|
|
173
|
+
- 🎞️ **Animations** — Typewriter, fade, slide, pulse, wave, glitch, reveal. AbortSignal-aware, reducedMotion mode
|
|
174
|
+
- ⏳ **Loaders** — 11 spinner styles, animated bars, hierarchical/parallel tasks, countdowns, multi-spinner manager
|
|
175
|
+
- 🎬 **Frames** — Sequenced playback with pause/resume/seek, live push-based renderer, drift-corrected timing, morph
|
|
176
|
+
- 🧱 **Components** — Tables (ANSI-aware, multi-line cells), badges, status lines, sections, columns, timelines, interactive menus
|
|
177
|
+
- 🎨 **Themes** — 8 built-ins (Dracula, Nord, Monokai, Cyberpunk, Pastel, Matrix, Ocean, Sunset). Per-instance isolation, `onChange` listeners, `bg*` helpers
|
|
178
|
+
- ⚙️ **Configure** — Centralized config with subscribers, batched updates, `withConfig()` temporary overrides, strict mode
|
|
179
|
+
- 🛠️ **Utils** — ANSI primitives, cursor control, terminal hyperlinks (OSC 8), `setTitle`, `safeJson`, `onResize`, debounce/throttle/memoize
|
|
154
180
|
|
|
155
181
|
---
|
|
156
182
|
|
|
157
183
|
## 📸 Showcase
|
|
158
184
|
|
|
159
185
|
### Colors & Gradients
|
|
160
|
-
<div align="center">
|
|
161
|
-
<img src="media/colors.png" alt="Colors and gradients" width="700"/>
|
|
162
|
-
</div>
|
|
163
186
|
|
|
164
|
-
|
|
165
|
-
import { color, gradient, rainbow, compose } from 'ansimax';
|
|
166
|
-
|
|
167
|
-
// 16, 256, and 24-bit colors
|
|
168
|
-
color.red('basic'); // 16-color
|
|
169
|
-
color.color256(196)('palette'); // 256-color
|
|
170
|
-
color.hex('#48dbfb')('truecolor'); // 24-bit
|
|
171
|
-
color.rgb(255, 100, 50)('custom'); // RGB
|
|
187
|
+
<img src="media/colors.png" alt="Colors and gradients" />
|
|
172
188
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
console.log(errorStyle('CRITICAL ERROR'));
|
|
189
|
+
```ts
|
|
190
|
+
import { color, gradient } from 'ansimax';
|
|
176
191
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
192
|
+
color.red('red'); color.green('green'); color.blue('blue');
|
|
193
|
+
color.bold(text); color.italic(text); color.underline(text);
|
|
194
|
+
gradient('fire to ocean', ['#ff6b6b', '#feca57', '#48dbfb']);
|
|
195
|
+
color.rainbow('built-in rainbow preset');
|
|
180
196
|
```
|
|
181
197
|
|
|
182
|
-
---
|
|
183
|
-
|
|
184
198
|
### ASCII Art
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
</div>
|
|
199
|
+
|
|
200
|
+
<img src="media/ascii_art.png" alt="ASCII art" />
|
|
188
201
|
|
|
189
202
|
```ts
|
|
190
|
-
import { ascii,
|
|
203
|
+
import { ascii, gradient } from 'ansimax';
|
|
191
204
|
|
|
192
|
-
ascii.
|
|
193
|
-
ascii.small('hello'); // 3-line compact font
|
|
194
|
-
ascii.banner('ANSIMAX', {
|
|
205
|
+
ascii.banner('HELLO', {
|
|
195
206
|
font: 'big',
|
|
196
|
-
colorFn: rainbow,
|
|
197
207
|
align: 'center',
|
|
208
|
+
colorFn: (t) => gradient(t, ['#ff79c6', '#bd93f9']),
|
|
198
209
|
});
|
|
199
210
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
borderStyle: 'double',
|
|
203
|
-
padding: 2,
|
|
204
|
-
});
|
|
211
|
+
ascii.box('Rainbow box!', { padding: 1, borderStyle: 'rounded' });
|
|
212
|
+
```
|
|
205
213
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
214
|
+
### Trees
|
|
215
|
+
|
|
216
|
+
<img src="media/trees.png" alt="Trees" />
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
import { tree, color } from 'ansimax';
|
|
220
|
+
|
|
221
|
+
const project = tree({ label: 'my-app', icon: '📦', color: color.bold });
|
|
222
|
+
const src = project.add({ label: 'src', icon: '📁' });
|
|
223
|
+
src.addLeaf({ label: 'index.ts', icon: '📄' });
|
|
224
|
+
src.addLeaf({ label: 'app.ts', icon: '📄' });
|
|
225
|
+
|
|
226
|
+
console.log(project.render({
|
|
227
|
+
style: 'rounded',
|
|
228
|
+
palette: [color.cyan, color.green, color.magenta],
|
|
229
|
+
guideColor: color.dim,
|
|
230
|
+
}));
|
|
211
231
|
```
|
|
212
232
|
|
|
213
|
-
|
|
233
|
+
### Pixel Art & Canvas
|
|
234
|
+
|
|
235
|
+
<img src="media/pixel_art.png" alt="Pixel art" />
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
import { images, createCanvas, gradientRect } from 'ansimax';
|
|
239
|
+
|
|
240
|
+
// Built-in sprite
|
|
241
|
+
console.log(images.sprite('heart'));
|
|
242
|
+
|
|
243
|
+
// Smooth gradient with Bayer dither
|
|
244
|
+
console.log(gradientRect({
|
|
245
|
+
width: 50, height: 4,
|
|
246
|
+
colors: ['#ff6b6b', '#feca57', '#48dbfb'],
|
|
247
|
+
dither: 'bayer',
|
|
248
|
+
}));
|
|
249
|
+
|
|
250
|
+
// Custom canvas
|
|
251
|
+
const c = createCanvas(40, 10);
|
|
252
|
+
c.fill({ r: 18, g: 18, b: 38 });
|
|
253
|
+
c.drawCircle(20, 5, 4, { r: 255, g: 200, b: 0 }, true);
|
|
254
|
+
c.drawSprite(2, 2, images.sprites.star!.pixels);
|
|
255
|
+
c.print();
|
|
256
|
+
```
|
|
214
257
|
|
|
215
258
|
### Components
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
</div>
|
|
259
|
+
|
|
260
|
+
<img src="media/components.png" alt="Components" />
|
|
219
261
|
|
|
220
262
|
```ts
|
|
221
|
-
import { components } from 'ansimax';
|
|
263
|
+
import { components, color } from 'ansimax';
|
|
222
264
|
|
|
223
|
-
// Tables with auto-sizing
|
|
224
265
|
components.table([
|
|
225
|
-
['
|
|
226
|
-
['
|
|
227
|
-
['
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
components.
|
|
232
|
-
components.
|
|
233
|
-
components.status('warn', 'Deprecation notice');
|
|
234
|
-
|
|
235
|
-
// Badges
|
|
236
|
-
components.badge('VERSION', 'v1.0.0');
|
|
237
|
-
components.badge('BUILD', 'passing');
|
|
238
|
-
|
|
239
|
-
// Interactive menus (with AbortSignal support)
|
|
240
|
-
const choice = await components.menu([
|
|
241
|
-
'Install dependencies',
|
|
242
|
-
'Run tests',
|
|
243
|
-
'Deploy',
|
|
244
|
-
'Cancel',
|
|
245
|
-
], { multiSelect: false });
|
|
266
|
+
['Module', 'Status', 'Coverage'],
|
|
267
|
+
['colors', color.green('● ready'), '100%'],
|
|
268
|
+
['animations', color.green('● ready'), '100%'],
|
|
269
|
+
['loaders', color.green('● ready'), '100%'],
|
|
270
|
+
], { borderStyle: 'rounded' });
|
|
271
|
+
|
|
272
|
+
components.badge('VERSION', 'v1.1.1');
|
|
273
|
+
components.badge('BUILD', 'passing');
|
|
246
274
|
```
|
|
247
275
|
|
|
248
|
-
---
|
|
249
|
-
|
|
250
276
|
### Timeline
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
</div>
|
|
277
|
+
|
|
278
|
+
<img src="media/timeline.png" alt="Timeline" />
|
|
254
279
|
|
|
255
280
|
```ts
|
|
256
281
|
components.timeline([
|
|
257
282
|
{ label: 'Project init', done: true, time: '10:00' },
|
|
258
283
|
{ label: 'Build pipeline', done: true, time: '10:15' },
|
|
259
|
-
{ label: 'Run tests', done:
|
|
260
|
-
{ label: 'Deploy to npm', done: false
|
|
284
|
+
{ label: 'Run tests', done: false, time: '10:32' },
|
|
285
|
+
{ label: 'Deploy to npm', done: false },
|
|
261
286
|
]);
|
|
262
287
|
```
|
|
263
288
|
|
|
264
|
-
---
|
|
265
|
-
|
|
266
289
|
### Loaders & Progress
|
|
267
|
-
<div align="center">
|
|
268
|
-
<img src="media/loaders.png" alt="Loaders and progress bars" width="700"/>
|
|
269
|
-
</div>
|
|
270
290
|
|
|
271
291
|
```ts
|
|
272
292
|
import { loader } from 'ansimax';
|
|
273
293
|
|
|
274
|
-
// Spinner
|
|
275
|
-
const stop = loader.spin('
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
signal: ctrl.signal, // AbortSignal aware
|
|
279
|
-
});
|
|
280
|
-
stop('Complete', true);
|
|
294
|
+
// Spinner with success/failure
|
|
295
|
+
const stop = loader.spin('Loading...', { color: '#bd93f9' });
|
|
296
|
+
await work();
|
|
297
|
+
stop('Done!', true); // ✓ green icon
|
|
281
298
|
|
|
282
299
|
// Animated progress bar
|
|
283
|
-
await loader.progressAnimate(
|
|
284
|
-
delay:
|
|
285
|
-
color: '#48dbfb',
|
|
300
|
+
await loader.progressAnimate(100, 'Downloading', {
|
|
301
|
+
color: '#50fa7b', delay: 25,
|
|
286
302
|
});
|
|
287
303
|
|
|
288
|
-
//
|
|
304
|
+
// Hierarchical tasks with parallel execution
|
|
289
305
|
await loader.tasks([
|
|
290
|
-
{ text: '
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
],
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
await loader.countdown(5, {
|
|
297
|
-
label: 'Launching in',
|
|
298
|
-
color: '#ffd700',
|
|
299
|
-
});
|
|
306
|
+
{ text: 'Build', fn: async () => build(), subtasks: [
|
|
307
|
+
{ text: 'TypeScript', fn: async () => tsc() },
|
|
308
|
+
{ text: 'Bundle', fn: async () => bundle() },
|
|
309
|
+
]},
|
|
310
|
+
{ text: 'Test', fn: async () => test() },
|
|
311
|
+
], { parallel: true });
|
|
300
312
|
```
|
|
301
313
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
### Pixel Art & Canvas
|
|
305
|
-
<div align="center">
|
|
306
|
-
<img src="media/pixel_art.png" alt="Pixel art and canvas drawing" width="700"/>
|
|
307
|
-
</div>
|
|
314
|
+
### Animations
|
|
308
315
|
|
|
309
316
|
```ts
|
|
310
|
-
import {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
// Sprite transforms
|
|
316
|
-
const flipped = images.flipHorizontal(images.sprites.heart.pixels);
|
|
317
|
-
const rotated = images.rotate90(images.sprites.star.pixels);
|
|
318
|
-
|
|
319
|
-
// Custom canvas drawing
|
|
320
|
-
const canvas = createCanvas(30, 10);
|
|
321
|
-
canvas.drawRect(0, 0, 30, 10, { r: 30, g: 30, b: 50 }, true);
|
|
322
|
-
canvas.drawCircle(15, 5, 4, { r: 255, g: 200, b: 0 }, true);
|
|
323
|
-
canvas.print();
|
|
324
|
-
|
|
325
|
-
// Gradient rectangles — horizontal, vertical, diagonal, radial
|
|
326
|
-
images.gradientRect({
|
|
327
|
-
width: 50, height: 8,
|
|
328
|
-
colors: ['#ff0080', '#7928ca', '#0070f3'],
|
|
329
|
-
style: 'radial',
|
|
317
|
+
import { animate, gradient } from 'ansimax';
|
|
318
|
+
|
|
319
|
+
await animate.typewriter('Welcome to the deployment wizard...', {
|
|
320
|
+
speed: 30,
|
|
321
|
+
colorFn: (t) => gradient(t, ['#bd93f9', '#ff79c6']),
|
|
330
322
|
});
|
|
331
|
-
```
|
|
332
323
|
|
|
333
|
-
|
|
324
|
+
await animate.fadeIn('Loading complete', { duration: 600 });
|
|
325
|
+
|
|
326
|
+
// Race steps against a timeout — never hang
|
|
327
|
+
await animate.parallel([
|
|
328
|
+
async () => await checkNetwork(),
|
|
329
|
+
async () => await checkDatabase(),
|
|
330
|
+
async () => await checkAuth(),
|
|
331
|
+
], { timeout: 5000 });
|
|
332
|
+
```
|
|
334
333
|
|
|
335
334
|
### Themes
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
</div>
|
|
335
|
+
|
|
336
|
+
<img src="media/themes.png" alt="Themes" />
|
|
339
337
|
|
|
340
338
|
```ts
|
|
341
|
-
import { themes,
|
|
342
|
-
|
|
343
|
-
// 8 built-in themes
|
|
344
|
-
themes.use('dracula'); // 'dracula', 'nord', 'monokai', 'cyberpunk',
|
|
345
|
-
// 'pastel', 'matrix', 'ocean', 'sunset', 'custom'
|
|
346
|
-
|
|
347
|
-
const t = themes.current();
|
|
348
|
-
console.log(color.hex(t.primary)('Primary text'));
|
|
349
|
-
console.log(color.hex(t.error)('Error message'));
|
|
350
|
-
console.log(color.hex(t.success)('Success!'));
|
|
351
|
-
|
|
352
|
-
// Define your own theme
|
|
353
|
-
themes.define('mytheme', {
|
|
354
|
-
primary: '#00ff88',
|
|
355
|
-
secondary: '#0070f3',
|
|
356
|
-
accent: '#ffd700',
|
|
357
|
-
error: '#ff4757',
|
|
358
|
-
warning: '#ffa502',
|
|
359
|
-
success: '#2ed573',
|
|
360
|
-
});
|
|
361
|
-
```
|
|
339
|
+
import { themes, createTheme } from 'ansimax';
|
|
362
340
|
|
|
363
|
-
|
|
341
|
+
// Built-in themes
|
|
342
|
+
themes.use('dracula');
|
|
343
|
+
themes.primary('hello');
|
|
364
344
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
345
|
+
// Listen for changes
|
|
346
|
+
const off = themes.onChange((newTheme, oldTheme) => {
|
|
347
|
+
console.log(`Theme: ${oldTheme.name} → ${newTheme.name}`);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// Multi-tenant: each instance fully isolated
|
|
351
|
+
const tenantA = createTheme('nord');
|
|
352
|
+
const tenantB = createTheme('matrix');
|
|
353
|
+
tenantA.register('custom', myDef); // doesn't leak to tenantB
|
|
354
|
+
```
|
|
369
355
|
|
|
370
356
|
---
|
|
371
357
|
|
|
372
|
-
## 📚
|
|
358
|
+
## 📚 Examples
|
|
373
359
|
|
|
374
|
-
|
|
360
|
+
Eleven production-grade examples ship in the npm package and are runnable directly. Find them in [`/examples`](./examples) once you install:
|
|
375
361
|
|
|
362
|
+
| File | What it demonstrates |
|
|
363
|
+
|---|---|
|
|
364
|
+
| `01-quick-smoke.ts` | Quick smoke test — verifies every major import works |
|
|
365
|
+
| `02-colors-gradients.ts` | Every color fn, gradient types, presets, compose, chain API |
|
|
366
|
+
| `03-ascii-banners.ts` | Banners (`big`/`small`), 6 box styles, dividers, logo composer |
|
|
367
|
+
| `04-trees.ts` | Tree builder + plain-data API, 4 styles, palettes, algorithms (walk/find/map/filter) |
|
|
368
|
+
| `05-components.ts` | Tables, badges, status, sections, columns, timelines, progress bars |
|
|
369
|
+
| `06-pixel-art.ts` | Sprites, custom canvas, gradient rects with dither, transforms (flip/rotate) |
|
|
370
|
+
| `07-animations.ts` | typewriter, fadeIn/Out, slide, pulse, wave, glitch, reveal |
|
|
371
|
+
| `08-loaders.ts` | spinner styles, animated progress, hierarchical tasks, countdown |
|
|
372
|
+
| `09-themes.ts` | All 8 built-in themes, listeners, custom theme registration, per-instance isolation |
|
|
373
|
+
| `10-everything.ts` | Comprehensive showcase — every module exercised in one cohesive demo |
|
|
374
|
+
| `all-in-one.mjs` | Full demo in **ESM** (plain JS with `import`) — no TypeScript needed |
|
|
375
|
+
| `all-in-one.cjs` | Full demo in **CommonJS** (plain JS with `require`) — no TypeScript needed |
|
|
376
|
+
|
|
377
|
+
Run any example with:
|
|
376
378
|
```bash
|
|
377
|
-
# TypeScript
|
|
378
|
-
npx tsx examples/
|
|
379
|
-
|
|
380
|
-
# JavaScript demo (CommonJS)
|
|
381
|
-
npm run build
|
|
382
|
-
node examples/demo.js
|
|
383
|
-
|
|
384
|
-
# Visual showcase (great for screenshots)
|
|
385
|
-
npx tsx examples/showcase.ts
|
|
379
|
+
# TypeScript examples
|
|
380
|
+
npx tsx examples/10-everything.ts
|
|
386
381
|
|
|
387
|
-
#
|
|
388
|
-
|
|
382
|
+
# Plain JS — ESM
|
|
383
|
+
node examples/all-in-one.mjs
|
|
389
384
|
|
|
390
|
-
#
|
|
391
|
-
|
|
385
|
+
# Plain JS — CommonJS
|
|
386
|
+
node examples/all-in-one.cjs
|
|
392
387
|
```
|
|
393
388
|
|
|
394
389
|
---
|
|
395
390
|
|
|
396
391
|
## 🎯 Use Cases
|
|
397
392
|
|
|
398
|
-
- **
|
|
399
|
-
- **
|
|
400
|
-
- **
|
|
401
|
-
- **
|
|
402
|
-
- **
|
|
403
|
-
- **
|
|
404
|
-
- **
|
|
393
|
+
- **CLI installers & scaffolders** — beautiful first-run experience (create-react-app, create-next-app style)
|
|
394
|
+
- **DevOps tools** — deployment dashboards, build pipelines, health monitors
|
|
395
|
+
- **Dev experience** — better test runners, lint output, error formatting
|
|
396
|
+
- **Interactive prompts** — menus, confirmations, multi-select wizards
|
|
397
|
+
- **Data exploration** — tables, trees, charts for terminal-first workflows
|
|
398
|
+
- **Status reporters** — real-time progress, multi-task orchestration
|
|
399
|
+
- **ASCII intros** — game launchers, demo splash screens, login banners
|
|
405
400
|
|
|
406
401
|
---
|
|
407
402
|
|
|
408
403
|
## ⚙️ Configuration
|
|
409
404
|
|
|
405
|
+
Global config affects every module that respects it (colors, themes, animation speed, etc.):
|
|
406
|
+
|
|
410
407
|
```ts
|
|
411
|
-
import { configure } from 'ansimax';
|
|
408
|
+
import { configure, getConfig, withConfig, onConfigKeyChange } from 'ansimax';
|
|
412
409
|
|
|
413
410
|
configure({
|
|
414
|
-
colorMode:
|
|
415
|
-
animationSpeed: 'normal',
|
|
411
|
+
colorMode: 'auto', // 'none' | 'basic' | '256' | 'truecolor' | 'auto'
|
|
412
|
+
animationSpeed: 'normal', // 'slow' | 'normal' | 'fast' | 'instant'
|
|
413
|
+
theme: 'dracula', // any registered theme
|
|
414
|
+
reducedMotion: false,
|
|
416
415
|
});
|
|
417
416
|
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
417
|
+
// Listen for changes (per-key — avoids over-firing)
|
|
418
|
+
const off = onConfigKeyChange('theme', (newTheme, oldTheme) => {
|
|
419
|
+
console.log(`Theme: ${oldTheme} → ${newTheme}`);
|
|
420
|
+
});
|
|
422
421
|
|
|
423
|
-
|
|
422
|
+
// Temporary override + auto-restore on completion or throw
|
|
423
|
+
await withConfig({ animationSpeed: 'fast' }, async () => {
|
|
424
|
+
await runDemo();
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// Strict mode catches config typos
|
|
428
|
+
configure({ unknwnKey: 'x' }, { strict: true }); // throws RangeError
|
|
429
|
+
```
|
|
424
430
|
|
|
425
431
|
---
|
|
426
432
|
|
|
427
433
|
## 🛣️ Roadmap
|
|
428
434
|
|
|
429
|
-
Ansimax is being built toward a full
|
|
435
|
+
Ansimax is being built toward a **full terminal rendering platform** — a Node-native answer to what Python developers get from `rich` + `textual` combined, with Node-specific improvements where it matters.
|
|
430
436
|
|
|
431
|
-
|
|
437
|
+
The roadmap intentionally targets — and aims to surpass — gaps that even mature Python TUI libraries haven't fully solved: live-diff renderers, animated gradients, terminal image protocols, and a true reactive layer.
|
|
432
438
|
|
|
433
|
-
|
|
434
|
-
- [x]
|
|
435
|
-
- [x]
|
|
436
|
-
- [x]
|
|
437
|
-
- [x]
|
|
439
|
+
### ✅ Phase 1 — Core foundation
|
|
440
|
+
- [x] Styling engine — ANSI 16 / 256 / truecolor with adaptive fallback
|
|
441
|
+
- [x] Hex + RGB helpers with clamping and validation
|
|
442
|
+
- [x] `NO_COLOR` / `FORCE_COLOR` env support + non-TTY auto-detection
|
|
443
|
+
- [x] `AbortSignal` integration across animations and loaders
|
|
444
|
+
- [x] `compose()` style stacking with single-reset emission
|
|
445
|
+
- [x] Bounded LRU escape cache (512 entries, packed-RGB keyed)
|
|
446
|
+
- [x] Custom preset registry (`registerPreset`, `listPresets`)
|
|
438
447
|
|
|
439
448
|
### ✅ Phase 2 — Gradient engine
|
|
440
|
-
|
|
441
449
|
- [x] Linear gradients (multi-stop)
|
|
442
|
-
- [x] Rainbow presets
|
|
450
|
+
- [x] Rainbow + 6 built-in presets
|
|
443
451
|
- [x] Radial gradients (in `gradientRect`)
|
|
444
452
|
- [x] Diagonal gradients
|
|
445
|
-
- [
|
|
453
|
+
- [x] Arbitrary-angle gradients
|
|
454
|
+
- [x] Bayer 4×4 dithering for smooth tonal transitions
|
|
455
|
+
- [x] Single-stop UX (CSS-style behavior)
|
|
456
|
+
- [ ] **Animated gradients** (color flow over time, infinite loops)
|
|
457
|
+
- [ ] **Gradient interpolation curves** (linear / ease-in / ease-out / cubic-bezier)
|
|
458
|
+
- [ ] **Conic gradients** (radial sweep)
|
|
446
459
|
|
|
447
460
|
### 🟡 Phase 3 — ASCII engine
|
|
448
|
-
|
|
449
461
|
- [x] Block fonts (`big`, `small`)
|
|
450
|
-
- [x] Banner with gradient + alignment
|
|
462
|
+
- [x] Banner with gradient + alignment + per-char coloring
|
|
451
463
|
- [x] Box drawing (6 border styles)
|
|
452
|
-
- [
|
|
464
|
+
- [x] Divider with style variants
|
|
465
|
+
- [x] Logo composer (gradient + box wrapping)
|
|
466
|
+
- [x] Custom font registry (`registerFont`, `hasFont`, `listFonts`)
|
|
467
|
+
- [x] Stream API (`ascii.stream()` with AbortSignal)
|
|
468
|
+
- [ ] **Image → ASCII** converter (with edge detection, Sobel/Canny)
|
|
453
469
|
- [ ] **Color ASCII** rendering (preserve image colors)
|
|
454
|
-
- [ ] **Image dithering** for better tonal range
|
|
470
|
+
- [ ] **Image dithering** for better tonal range (Floyd-Steinberg)
|
|
455
471
|
- [ ] **Face-optimized ASCII** (high-detail mode for portraits)
|
|
472
|
+
- [ ] **Figlet font support** (.flf file loader — 250+ community fonts)
|
|
456
473
|
|
|
457
474
|
### ✅ Phase 4 — Terminal UI primitives
|
|
458
|
-
|
|
459
|
-
- [x] Tables (irregular rows, jagged data)
|
|
475
|
+
- [x] Tables (irregular rows, multi-line cells, ANSI-aware)
|
|
460
476
|
- [x] Boxes with multiple styles
|
|
461
|
-
- [x] Status messages + badges
|
|
477
|
+
- [x] Status messages + badges (with border option)
|
|
462
478
|
- [x] Timelines with done/pending states
|
|
463
479
|
- [x] Interactive menus (single + multi-select)
|
|
464
|
-
- [
|
|
465
|
-
- [
|
|
480
|
+
- [x] Columns layout (truncate/wrap overflow)
|
|
481
|
+
- [x] Sections (gradient headers with auto-width)
|
|
482
|
+
- [x] Trees (collapsible, max-depth, cycle-safe)
|
|
483
|
+
- [ ] **Panels** (split layouts: hsplit, vsplit)
|
|
466
484
|
- [ ] **Layouts** (flexbox-style positioning)
|
|
485
|
+
- [ ] **Grid system** (CSS Grid-inspired column/row spans)
|
|
486
|
+
- [ ] **Markdown rendering** (headings, lists, code blocks, tables)
|
|
487
|
+
- [ ] **Syntax highlighting** (built-in language grammars)
|
|
488
|
+
- [ ] **JSON/YAML pretty-printing** (with depth limit + collapse)
|
|
489
|
+
- [ ] **Logging integration** (drop-in replacement for `console`/`pino`/`winston` transports)
|
|
467
490
|
|
|
468
491
|
### ✅ Phase 5 — Cursor & screen control
|
|
469
|
-
|
|
470
|
-
- [x] Cursor visibility, save/restore, positioning
|
|
492
|
+
- [x] Cursor visibility, save/restore, positioning, line navigation
|
|
471
493
|
- [x] Screen clearing (line, area, full)
|
|
472
|
-
- [x]
|
|
494
|
+
- [x] Reference-counted cursor (overlapping calls safe)
|
|
495
|
+
- [x] Crash-safe restore (exit/SIGINT/SIGTERM handlers)
|
|
496
|
+
- [x] Terminal hyperlinks (OSC 8)
|
|
497
|
+
- [x] Window title (OSC 2)
|
|
498
|
+
- [x] Bell (BEL)
|
|
473
499
|
|
|
474
500
|
### ✅ Phase 6 — Animation engine
|
|
475
|
-
|
|
476
501
|
- [x] Typewriter, fadeIn, fadeOut, slide, pulse, wave, glitch, reveal
|
|
477
502
|
- [x] All `AbortSignal`-aware
|
|
478
503
|
- [x] `reducedMotion` mode for accessibility
|
|
479
|
-
- [x]
|
|
504
|
+
- [x] Frame morph (text → text interpolation, cinematic decryption)
|
|
505
|
+
- [x] `parallel()` with timeout
|
|
506
|
+
- [x] Signal propagation to nested animations
|
|
507
|
+
- [ ] **Easing functions library** (24 standard easings: cubic, elastic, bounce, back)
|
|
508
|
+
- [ ] **Animation composition** (`parallel + sequence + delay` DSL)
|
|
509
|
+
- [ ] **Spring physics** animations (`react-spring` style)
|
|
510
|
+
- [ ] **Tween engine** (interpolate any value type)
|
|
480
511
|
|
|
481
512
|
### 🟡 Phase 7 — Progress ecosystem
|
|
482
|
-
|
|
483
513
|
- [x] Spinners (11 styles) with color + AbortSignal
|
|
484
514
|
- [x] Animated progress bars
|
|
485
515
|
- [x] Multi-task runners (sequential + parallel)
|
|
486
516
|
- [x] Countdown timers
|
|
487
|
-
- [
|
|
488
|
-
- [
|
|
489
|
-
- [ ] **Live
|
|
517
|
+
- [x] Multi-spinner manager (stacked concurrent spinners)
|
|
518
|
+
- [x] Hierarchical tasks (parent + subtasks rollup)
|
|
519
|
+
- [ ] **Live ETA estimation** (rolling average + Kalman filter projection)
|
|
520
|
+
- [ ] **Live refresh diff renderer** (no flicker, only redraw changed lines)
|
|
521
|
+
- [ ] **Progress groups** (named groups with shared theme)
|
|
522
|
+
- [ ] **Throughput meters** (bytes/sec, ops/sec with auto-scaling units)
|
|
490
523
|
|
|
491
524
|
### 🟡 Phase 8 — Capability detection
|
|
492
|
-
|
|
493
525
|
- [x] TTY detection (auto-disable in pipes/CI)
|
|
494
|
-
- [x] `NO_COLOR` env support
|
|
495
|
-
- [
|
|
496
|
-
- [
|
|
497
|
-
- [
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
- [ ] **
|
|
526
|
+
- [x] `NO_COLOR` / `FORCE_COLOR` env support
|
|
527
|
+
- [x] Color depth detection (16 / 256 / truecolor)
|
|
528
|
+
- [x] CI provider detection (GitHub Actions, CircleCI, GitLab, Buildkite, Drone, Travis)
|
|
529
|
+
- [x] Terminal program detection (iTerm, vscode, WezTerm, Hyper, Apple_Terminal)
|
|
530
|
+
- [x] Windows Terminal detection (`WT_SESSION`)
|
|
531
|
+
- [ ] **Unicode width detection** (CJK halfwidth/fullwidth, emoji clusters, ZWJ sequences)
|
|
532
|
+
- [ ] **Image protocol detection** (Sixel, iTerm inline images, Kitty graphics protocol)
|
|
533
|
+
- [ ] **Terminal capability database** (full xterm capability flags + version probes)
|
|
534
|
+
- [ ] **Font metrics detection** (cell width/height for pixel-accurate layouts)
|
|
535
|
+
|
|
536
|
+
### 🟡 Phase 9 — Advanced rendering
|
|
537
|
+
- [x] Dirty-rectangle canvas (only redraw changed pixels)
|
|
538
|
+
- [x] Bounded LRU caches (escape sequences, render cache, ANSI cache)
|
|
539
|
+
- [x] Drift-corrected timing (animations stay locked to wall-clock)
|
|
540
|
+
- [ ] **Diff renderer** (line-level damage tracking for full UIs)
|
|
502
541
|
- [ ] **Virtual buffer** (compose UI without writing to stdout)
|
|
503
|
-
- [ ] **Z-index / layering**
|
|
504
|
-
- [ ] **Mouse event support**
|
|
542
|
+
- [ ] **Z-index / layering** (overlap panels with priority)
|
|
543
|
+
- [ ] **Mouse event support** (click, hover, drag, scroll wheel)
|
|
544
|
+
- [ ] **Keyboard event abstraction** (arrow keys, modifiers, key sequences, dead keys)
|
|
545
|
+
- [ ] **Full TUI framework** (reactive components — Textual-equivalent for Node)
|
|
505
546
|
|
|
506
547
|
### 🔴 Phase 10 — Terminal charts
|
|
507
|
-
|
|
508
|
-
- [ ] Bar charts (horizontal + vertical)
|
|
548
|
+
- [ ] Bar charts (horizontal + vertical, grouped, stacked)
|
|
509
549
|
- [ ] Line charts (with braille for sub-character resolution)
|
|
510
|
-
- [ ] Sparklines
|
|
511
|
-
- [ ]
|
|
512
|
-
- [ ]
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
550
|
+
- [ ] Sparklines (inline mini-charts for status bars)
|
|
551
|
+
- [ ] Area charts (filled with gradients)
|
|
552
|
+
- [ ] Heatmaps (color-mapped 2D grids)
|
|
553
|
+
- [ ] Pie / donut charts (with percentage labels)
|
|
554
|
+
- [ ] Scatter plots
|
|
555
|
+
- [ ] Box plots / candlestick charts
|
|
556
|
+
- [ ] Real-time streaming charts (live data feed with rolling window)
|
|
557
|
+
- [ ] **Plot composer** (multi-chart dashboards with shared axes)
|
|
558
|
+
|
|
559
|
+
### 🔴 Phase 11 — Forms & Input
|
|
560
|
+
- [ ] Text input prompts (with autocomplete + history)
|
|
561
|
+
- [ ] Password prompts (masked, strength meter)
|
|
562
|
+
- [ ] Confirm dialogs (yes/no with default highlight)
|
|
563
|
+
- [ ] Numeric input (with min/max validation)
|
|
564
|
+
- [ ] Date/time pickers (calendar widget)
|
|
565
|
+
- [ ] File picker (filesystem navigator)
|
|
566
|
+
- [ ] Form composer (multi-field with validation + error display)
|
|
567
|
+
- [ ] **Wizard flows** (multi-step forms with back/forward, progress indicator)
|
|
568
|
+
|
|
569
|
+
### 🔴 Phase 12 — Image & media
|
|
570
|
+
- [ ] Sixel image rendering (xterm, mlterm, WezTerm)
|
|
571
|
+
- [ ] iTerm2 inline images (base64 protocol)
|
|
572
|
+
- [ ] Kitty graphics protocol
|
|
573
|
+
- [ ] PNG/JPEG → terminal image (auto-detect best protocol)
|
|
574
|
+
- [ ] Video preview (frame-by-frame at low FPS)
|
|
575
|
+
- [ ] QR code generation (with size + ECC level options)
|
|
576
|
+
- [ ] Bar code generation (Code 128, EAN-13)
|
|
577
|
+
|
|
578
|
+
### 🔴 Phase 13 — Plugin system
|
|
516
579
|
- [ ] Plugin API for custom components
|
|
517
580
|
- [ ] Theme marketplace
|
|
518
|
-
- [ ] Custom font registration
|
|
581
|
+
- [ ] Custom font registration via npm packages
|
|
519
582
|
- [ ] Community animations registry
|
|
583
|
+
- [ ] Capability provider interface (plug in custom detectors)
|
|
584
|
+
- [ ] Renderer plugins (swap stdout for any writable stream)
|
|
585
|
+
|
|
586
|
+
### 🔴 Phase 14 — Reactivity layer (TUI framework)
|
|
587
|
+
- [ ] **Component lifecycle** (mount/unmount/update hooks)
|
|
588
|
+
- [ ] **Reactive state** (auto re-render on data change, signals or hooks)
|
|
589
|
+
- [ ] **Virtual DOM diffing** (line-level updates)
|
|
590
|
+
- [ ] **Event bus** (component communication)
|
|
591
|
+
- [ ] **Application loop** (single render tree with full lifecycle)
|
|
592
|
+
- [ ] **Routing** (multi-screen apps with history)
|
|
593
|
+
- [ ] **DevTools integration** (inspect component tree, mark changed nodes)
|
|
594
|
+
- [ ] **CSS-in-TS styling** (scoped styles per component)
|
|
520
595
|
|
|
521
596
|
**Legend:** ✅ Complete · 🟡 Partial · 🔴 Planned
|
|
522
597
|
|
|
@@ -524,20 +599,25 @@ Ansimax is being built toward a full **terminal rendering platform**. Here's wha
|
|
|
524
599
|
|
|
525
600
|
## 🧪 Testing
|
|
526
601
|
|
|
527
|
-
Ansimax ships with **750+ tests** and **100% line coverage**:
|
|
528
|
-
|
|
529
602
|
```bash
|
|
530
|
-
npm test
|
|
531
|
-
npm run test:
|
|
532
|
-
npm run
|
|
603
|
+
npm test # Run all 1700+ tests
|
|
604
|
+
npm run test:watch # Watch mode
|
|
605
|
+
npm run test:coverage # Coverage report
|
|
533
606
|
```
|
|
534
607
|
|
|
608
|
+
Coverage targets:
|
|
609
|
+
- Statements: **98%**
|
|
610
|
+
- Branches: **95%**
|
|
611
|
+
- Functions: **99%**
|
|
612
|
+
- Lines: **99%**
|
|
613
|
+
|
|
535
614
|
---
|
|
536
615
|
|
|
537
616
|
## 🛠️ Requirements
|
|
538
617
|
|
|
539
|
-
- Node.js
|
|
540
|
-
-
|
|
618
|
+
- **Node.js** ≥ 18
|
|
619
|
+
- **TypeScript** ≥ 5.0 (for typed consumption — optional)
|
|
620
|
+
- **Terminal** with truecolor support recommended (Windows Terminal, iTerm2, WezTerm, Kitty, modern xterm). Gracefully degrades to 256 / 16 / no-color.
|
|
541
621
|
|
|
542
622
|
---
|
|
543
623
|
|
|
@@ -546,84 +626,128 @@ npm run typecheck # Strict TypeScript check
|
|
|
546
626
|
```
|
|
547
627
|
ansimax/
|
|
548
628
|
├── src/
|
|
549
|
-
│ ├── colors/
|
|
550
|
-
│ ├──
|
|
551
|
-
│ ├── ascii/
|
|
552
|
-
│ ├──
|
|
553
|
-
│ ├── loaders/
|
|
554
|
-
│ ├── frames/
|
|
555
|
-
│ ├──
|
|
556
|
-
│ ├──
|
|
557
|
-
│ ├──
|
|
558
|
-
│
|
|
559
|
-
|
|
560
|
-
├──
|
|
561
|
-
└──
|
|
629
|
+
│ ├── colors/ Color rendering + gradient engine
|
|
630
|
+
│ ├── themes/ Theme system + 8 built-ins
|
|
631
|
+
│ ├── ascii/ Banners, boxes, fonts
|
|
632
|
+
│ ├── animations/ Typewriter, fade, slide, pulse, wave, glitch, reveal
|
|
633
|
+
│ ├── loaders/ Spinners, progress, tasks, multi-loader
|
|
634
|
+
│ ├── frames/ Sequenced playback + live renderer + morph
|
|
635
|
+
│ ├── components/ Tables, badges, status, timelines, menus
|
|
636
|
+
│ ├── images/ Sprites, canvas, dithered gradients
|
|
637
|
+
│ ├── trees/ Tree builder + algorithms
|
|
638
|
+
│ ├── utils/ ANSI primitives + helpers
|
|
639
|
+
│ └── configure.ts Global config + subscribers
|
|
640
|
+
├── examples/ 10 examples (TS) + 2 (JS — ESM & CJS) — all features covered
|
|
641
|
+
└── __tests__/ 16 test suites, 1700+ tests
|
|
562
642
|
```
|
|
563
643
|
|
|
564
644
|
---
|
|
565
645
|
|
|
646
|
+
## 📝 Changelog
|
|
647
|
+
|
|
648
|
+
### v1.1.1 — Bug fixes + cleaner examples
|
|
649
|
+
|
|
650
|
+
Patch release fixing two bugs from real-world v1.1.0 testing, plus a refreshed examples folder.
|
|
651
|
+
|
|
652
|
+
- 🐛 **Fixed `box()` crash** with `padding: { x, y }` — now gracefully falls back to default for non-numeric padding (also handles NaN, Infinity, strings)
|
|
653
|
+
- 🐛 **Fixed `components.menu()` cursor leak** on abrupt exit (Ctrl+C, SIGTERM) — emergency cleanup handlers now restore the cursor even when the process is killed mid-menu
|
|
654
|
+
- 📚 **New examples** — 10 TypeScript examples + 2 plain JS variants (`all-in-one.mjs` for ESM, `all-in-one.cjs` for CommonJS)
|
|
655
|
+
- 📖 **READMEs updated** — preview GIFs in the header, comprehensive showcase GIF in the footer
|
|
656
|
+
|
|
657
|
+
No API changes — drop-in replacement for `1.1.0`.
|
|
658
|
+
|
|
659
|
+
### v1.1.0 — Comprehensive hardening + new features
|
|
660
|
+
|
|
661
|
+
A massive robustness pass across every module, plus a new `trees` module. **100% backward compatible** — every existing API works identically.
|
|
662
|
+
|
|
663
|
+
**Highlights:**
|
|
664
|
+
|
|
665
|
+
- 🌳 **New `trees` module** — builder API + plain-data API, 4 styles, cycle detection, algorithms (`walk`, `find`, `count`, `map`, `filter`)
|
|
666
|
+
- ⚙️ **`configure.ts` upgrades** — `onConfigKeyChange`, `pauseListeners` / `resumeListeners`, `withConfig()`, strict mode
|
|
667
|
+
- 🎨 **Themes** — per-instance isolation (multi-tenant safe), `tryUse`, `onChange` listeners, `unregister`, `bg*` helpers, dynamic `style(name)` accessor
|
|
668
|
+
- 🌈 **Colors** — `registerPreset` / `listPresets`, bounded LRU escape cache, NaN/Infinity-safe RGB, single-stop gradient UX
|
|
669
|
+
- 🖼️ **Images** — `Pixel` / `PixelGrid` exported, deep-clone `canvas.pixels`, defensive coords, ANSI cache LRU bounded
|
|
670
|
+
- 🔠 **ASCII** — `hasFont`, `measure`, `stream` with AbortSignal, grapheme-aware
|
|
671
|
+
- 🎞️ **Frames** — ref-counted cursor, crash-safe restore, `repeat: 0` = infinite, fps cap at 60, drift correction
|
|
672
|
+
- 🧱 **Components** — `menu([])` returns `MENU_CANCELLED` (no throw), defensive numeric inputs everywhere
|
|
673
|
+
- 🛠️ **Utils** — `setTitle`, `link` (OSC 8 hyperlinks), `bell`, `safeJson` (BigInt + circular), `once`, `escapeRegex`, `padBoth`, `nextTick`, `memoize` with custom keyFn, `debounce` with `maxWait`, throttled `onResize`
|
|
674
|
+
- 🧪 **Tests** — ~1700+ tests across 16 suites, all green, ~98% coverage
|
|
675
|
+
|
|
676
|
+
See [CHANGELOG.md](CHANGELOG.md) for the complete version history with per-module breakdowns.
|
|
677
|
+
|
|
678
|
+
### v1.0.0 — Initial release
|
|
679
|
+
|
|
680
|
+
- Core modules: `color`, `animate`, `ascii`, `loader`, `frames`, `components`, `themes`, `images`, `configure`
|
|
681
|
+
- TypeScript types exported, ESM + CJS dual build
|
|
682
|
+
- Adaptive color rendering (NO_COLOR / FORCE_COLOR / TTY detection)
|
|
683
|
+
- `AbortSignal` support across all blocking APIs
|
|
684
|
+
- 750+ tests, 85%+ coverage
|
|
685
|
+
|
|
686
|
+
---
|
|
687
|
+
|
|
566
688
|
## 🤝 Contributing
|
|
567
689
|
|
|
568
|
-
Contributions
|
|
690
|
+
Contributions welcome! Areas where help is especially appreciated:
|
|
569
691
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
692
|
+
- New animation presets (easing, spring physics)
|
|
693
|
+
- Additional ASCII fonts (figlet `.flf` parser)
|
|
694
|
+
- Terminal capability database entries
|
|
695
|
+
- Translations (es, fr, de, ja, ...)
|
|
696
|
+
- Real-world example apps
|
|
697
|
+
- Chart implementations (Phase 10)
|
|
576
698
|
|
|
577
|
-
|
|
578
|
-
- All tests pass: `npm test`
|
|
579
|
-
- TypeScript is happy: `npm run typecheck`
|
|
580
|
-
- Code follows the existing style
|
|
699
|
+
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
581
700
|
|
|
582
701
|
---
|
|
583
702
|
|
|
584
703
|
## 🐛 Reporting Issues
|
|
585
704
|
|
|
586
|
-
Found a bug
|
|
705
|
+
Found a bug? Have a feature request? [Open an issue](https://github.com/Brashkie/ansimax/issues/new).
|
|
706
|
+
|
|
707
|
+
For security disclosures, please email [security@brashkie.dev](mailto:security@brashkie.dev) instead of opening a public issue.
|
|
587
708
|
|
|
588
709
|
---
|
|
589
710
|
|
|
590
711
|
## ⭐ Support
|
|
591
712
|
|
|
592
|
-
If you
|
|
713
|
+
If Ansimax saves you time, please star the repo on [GitHub](https://github.com/Brashkie/ansimax) — it helps the project grow and accelerates the roadmap.
|
|
714
|
+
|
|
715
|
+
---
|
|
593
716
|
|
|
594
|
-
|
|
595
|
-
- 🐛 **Report bugs** — open an [issue](https://github.com/Brashkie/ansimax/issues)
|
|
596
|
-
- 🚀 **Use it in your CLI projects** — that's the best support there is
|
|
597
|
-
- 📢 **Share it** — tweet, blog, mention it to a colleague who builds CLIs
|
|
598
|
-
- 💬 **Spread the word** — tag your CLI with `#ansimax` so others can find inspiration
|
|
717
|
+
## 👨💻 Author
|
|
599
718
|
|
|
600
|
-
|
|
719
|
+
**Brashkie** · [@Brashkie](https://github.com/Brashkie)
|
|
601
720
|
|
|
602
721
|
---
|
|
603
722
|
|
|
604
|
-
##
|
|
723
|
+
## 🎬 Full showcase
|
|
605
724
|
|
|
606
|
-
|
|
725
|
+
<div align="center">
|
|
607
726
|
|
|
608
|
-
|
|
727
|
+
<img src="media/all-ansimax.gif" alt="Ansimax full showcase — everything in action" width="720"/>
|
|
609
728
|
|
|
610
|
-
|
|
729
|
+
_All features in action — typewriter, gradients, ASCII banners, trees, tables, spinners, themes, and pixel art_
|
|
611
730
|
|
|
612
|
-
|
|
731
|
+
</div>
|
|
613
732
|
|
|
614
733
|
---
|
|
615
734
|
|
|
616
735
|
## 📜 License
|
|
617
736
|
|
|
618
|
-
[
|
|
737
|
+
[Apache License 2.0](LICENSE) © 2026 Brashkie
|
|
738
|
+
|
|
739
|
+
Ansimax is licensed under the **Apache License, Version 2.0** — a permissive license that allows commercial use, modification, distribution, and includes an explicit patent grant. See the [LICENSE](LICENSE) file for the full text.
|
|
619
740
|
|
|
620
741
|
---
|
|
621
742
|
|
|
622
|
-
**Keywords:** cli, terminal, ansi, colors, gradients, animation, spinner, ascii, ascii-art, pixel-art, progress-bar, loader, components, table, banner, theme, typescript, nodejs, zero-dependencies
|
|
743
|
+
**Keywords:** cli, terminal, ansi, colors, gradients, animation, spinner, ascii, ascii-art, pixel-art, progress-bar, loader, components, table, banner, theme, tree, trees, tui, typescript, nodejs, zero-dependencies, chalk, ora, boxen, figlet, inquirer
|
|
623
744
|
|
|
624
745
|
---
|
|
625
746
|
|
|
626
747
|
<div align="center">
|
|
627
|
-
|
|
628
|
-
|
|
748
|
+
|
|
749
|
+
**Built with ❤️ and TypeScript**
|
|
750
|
+
|
|
751
|
+
If Ansimax helps you ship better CLIs, give it a ⭐ on [GitHub](https://github.com/Brashkie/ansimax)!
|
|
752
|
+
|
|
629
753
|
</div>
|