cc-face 0.1.10

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.
Files changed (160) hide show
  1. package/README.md +102 -0
  2. package/dist/bin/cli.d.ts +2 -0
  3. package/dist/bin/cli.js +142 -0
  4. package/dist/bin/cli.js.map +1 -0
  5. package/dist/src/config.d.ts +24 -0
  6. package/dist/src/config.js +32 -0
  7. package/dist/src/config.js.map +1 -0
  8. package/dist/src/face.d.ts +59 -0
  9. package/dist/src/face.js +493 -0
  10. package/dist/src/face.js.map +1 -0
  11. package/dist/src/frames.d.ts +1 -0
  12. package/dist/src/frames.js +6 -0
  13. package/dist/src/frames.js.map +1 -0
  14. package/dist/src/generator.d.ts +16 -0
  15. package/dist/src/generator.js +122 -0
  16. package/dist/src/generator.js.map +1 -0
  17. package/dist/src/ipc.d.ts +34 -0
  18. package/dist/src/ipc.js +203 -0
  19. package/dist/src/ipc.js.map +1 -0
  20. package/dist/src/loader.d.ts +12 -0
  21. package/dist/src/loader.js +63 -0
  22. package/dist/src/loader.js.map +1 -0
  23. package/dist/src/main.d.ts +2 -0
  24. package/dist/src/main.js +210 -0
  25. package/dist/src/main.js.map +1 -0
  26. package/dist/src/patterns.d.ts +6 -0
  27. package/dist/src/patterns.js +14 -0
  28. package/dist/src/patterns.js.map +1 -0
  29. package/dist/src/pty.d.ts +17 -0
  30. package/dist/src/pty.js +84 -0
  31. package/dist/src/pty.js.map +1 -0
  32. package/dist/src/scroll.d.ts +36 -0
  33. package/dist/src/scroll.js +56 -0
  34. package/dist/src/scroll.js.map +1 -0
  35. package/dist/src/state.d.ts +36 -0
  36. package/dist/src/state.js +164 -0
  37. package/dist/src/state.js.map +1 -0
  38. package/dist/src/theme.d.ts +15 -0
  39. package/dist/src/theme.js +51 -0
  40. package/dist/src/theme.js.map +1 -0
  41. package/dist/src/types.d.ts +60 -0
  42. package/dist/src/types.js +3 -0
  43. package/dist/src/types.js.map +1 -0
  44. package/dist/src/utils.d.ts +8 -0
  45. package/dist/src/utils.js +13 -0
  46. package/dist/src/utils.js.map +1 -0
  47. package/faces/idle/config.json +7 -0
  48. package/faces/idle/img/1.jpeg +0 -0
  49. package/faces/idle/img/10.jpeg +0 -0
  50. package/faces/idle/img/11.jpeg +0 -0
  51. package/faces/idle/img/12.jpeg +0 -0
  52. package/faces/idle/img/13.jpeg +0 -0
  53. package/faces/idle/img/14.jpeg +0 -0
  54. package/faces/idle/img/15.jpeg +0 -0
  55. package/faces/idle/img/16.jpeg +0 -0
  56. package/faces/idle/img/17.jpeg +0 -0
  57. package/faces/idle/img/18.jpeg +0 -0
  58. package/faces/idle/img/19.jpeg +0 -0
  59. package/faces/idle/img/2.jpeg +0 -0
  60. package/faces/idle/img/20.jpeg +0 -0
  61. package/faces/idle/img/21.jpeg +0 -0
  62. package/faces/idle/img/22.jpeg +0 -0
  63. package/faces/idle/img/23.jpeg +0 -0
  64. package/faces/idle/img/24.jpeg +0 -0
  65. package/faces/idle/img/25.jpeg +0 -0
  66. package/faces/idle/img/26.jpeg +0 -0
  67. package/faces/idle/img/27.jpeg +0 -0
  68. package/faces/idle/img/28.jpeg +0 -0
  69. package/faces/idle/img/29.jpeg +0 -0
  70. package/faces/idle/img/3.jpeg +0 -0
  71. package/faces/idle/img/30.jpeg +0 -0
  72. package/faces/idle/img/4.jpeg +0 -0
  73. package/faces/idle/img/5.jpeg +0 -0
  74. package/faces/idle/img/6.jpeg +0 -0
  75. package/faces/idle/img/7.jpeg +0 -0
  76. package/faces/idle/img/8.jpeg +0 -0
  77. package/faces/idle/img/9.jpeg +0 -0
  78. package/faces/listening/config.json +5 -0
  79. package/faces/listening/img/1.jpeg +0 -0
  80. package/faces/listening/img/10.jpeg +0 -0
  81. package/faces/listening/img/11.jpeg +0 -0
  82. package/faces/listening/img/12.jpeg +0 -0
  83. package/faces/listening/img/13.jpeg +0 -0
  84. package/faces/listening/img/14.jpeg +0 -0
  85. package/faces/listening/img/15.jpeg +0 -0
  86. package/faces/listening/img/16.jpeg +0 -0
  87. package/faces/listening/img/17.jpeg +0 -0
  88. package/faces/listening/img/18.jpeg +0 -0
  89. package/faces/listening/img/19.jpeg +0 -0
  90. package/faces/listening/img/2.jpeg +0 -0
  91. package/faces/listening/img/20.jpeg +0 -0
  92. package/faces/listening/img/21.jpeg +0 -0
  93. package/faces/listening/img/22.jpeg +0 -0
  94. package/faces/listening/img/23.jpeg +0 -0
  95. package/faces/listening/img/24.jpeg +0 -0
  96. package/faces/listening/img/25.jpeg +0 -0
  97. package/faces/listening/img/26.jpeg +0 -0
  98. package/faces/listening/img/27.jpeg +0 -0
  99. package/faces/listening/img/3.jpeg +0 -0
  100. package/faces/listening/img/4.jpeg +0 -0
  101. package/faces/listening/img/5.jpeg +0 -0
  102. package/faces/listening/img/6.jpeg +0 -0
  103. package/faces/listening/img/7.jpeg +0 -0
  104. package/faces/listening/img/8.jpeg +0 -0
  105. package/faces/listening/img/9.jpeg +0 -0
  106. package/faces/thinking/config.json +5 -0
  107. package/faces/thinking/img/1.jpeg +0 -0
  108. package/faces/thinking/img/10.jpeg +0 -0
  109. package/faces/thinking/img/11.jpeg +0 -0
  110. package/faces/thinking/img/12.jpeg +0 -0
  111. package/faces/thinking/img/13.jpeg +0 -0
  112. package/faces/thinking/img/14.jpeg +0 -0
  113. package/faces/thinking/img/15.jpeg +0 -0
  114. package/faces/thinking/img/16.jpeg +0 -0
  115. package/faces/thinking/img/17.jpeg +0 -0
  116. package/faces/thinking/img/18.jpeg +0 -0
  117. package/faces/thinking/img/19.jpeg +0 -0
  118. package/faces/thinking/img/2.jpeg +0 -0
  119. package/faces/thinking/img/20.jpeg +0 -0
  120. package/faces/thinking/img/3.jpeg +0 -0
  121. package/faces/thinking/img/4.jpeg +0 -0
  122. package/faces/thinking/img/5.jpeg +0 -0
  123. package/faces/thinking/img/6.jpeg +0 -0
  124. package/faces/thinking/img/7.jpeg +0 -0
  125. package/faces/thinking/img/8.jpeg +0 -0
  126. package/faces/thinking/img/9.jpeg +0 -0
  127. package/faces/typing/config.json +5 -0
  128. package/faces/typing/img/1.jpeg +0 -0
  129. package/faces/typing/img/10.jpeg +0 -0
  130. package/faces/typing/img/11.jpeg +0 -0
  131. package/faces/typing/img/12.jpeg +0 -0
  132. package/faces/typing/img/13.jpeg +0 -0
  133. package/faces/typing/img/14.jpeg +0 -0
  134. package/faces/typing/img/15.jpeg +0 -0
  135. package/faces/typing/img/16.jpeg +0 -0
  136. package/faces/typing/img/17.jpeg +0 -0
  137. package/faces/typing/img/18.jpeg +0 -0
  138. package/faces/typing/img/19.jpeg +0 -0
  139. package/faces/typing/img/2.jpeg +0 -0
  140. package/faces/typing/img/20.jpeg +0 -0
  141. package/faces/typing/img/21.jpeg +0 -0
  142. package/faces/typing/img/22.jpeg +0 -0
  143. package/faces/typing/img/23.jpeg +0 -0
  144. package/faces/typing/img/24.jpeg +0 -0
  145. package/faces/typing/img/25.jpeg +0 -0
  146. package/faces/typing/img/26.jpeg +0 -0
  147. package/faces/typing/img/27.jpeg +0 -0
  148. package/faces/typing/img/28.jpeg +0 -0
  149. package/faces/typing/img/29.jpeg +0 -0
  150. package/faces/typing/img/3.jpeg +0 -0
  151. package/faces/typing/img/30.jpeg +0 -0
  152. package/faces/typing/img/31.jpeg +0 -0
  153. package/faces/typing/img/32.jpeg +0 -0
  154. package/faces/typing/img/4.jpeg +0 -0
  155. package/faces/typing/img/5.jpeg +0 -0
  156. package/faces/typing/img/6.jpeg +0 -0
  157. package/faces/typing/img/7.jpeg +0 -0
  158. package/faces/typing/img/8.jpeg +0 -0
  159. package/faces/typing/img/9.jpeg +0 -0
  160. package/package.json +36 -0
@@ -0,0 +1,493 @@
1
+ import { colorForRole } from './theme.js';
2
+ import { config } from './config.js';
3
+ import { hasDecodedFrames, buildFace } from './loader.js';
4
+ // ── Helper ──────────────────────────────────────────────────────────
5
+ /**
6
+ * Render a single art row with ANSI color spans applied.
7
+ * Accepts pre-sorted spans for this specific row only.
8
+ */
9
+ export function renderRow(art, rowSpans, theme) {
10
+ if (rowSpans.length === 0) {
11
+ return art;
12
+ }
13
+ let result = '';
14
+ let spanIdx = 0;
15
+ let inSpan = false;
16
+ for (let col = 0; col < art.length; col++) {
17
+ // Check if we are leaving the current span
18
+ if (inSpan && spanIdx < rowSpans.length) {
19
+ const cur = rowSpans[spanIdx];
20
+ if (col >= cur.col + cur.len) {
21
+ result += theme.reset;
22
+ inSpan = false;
23
+ spanIdx++;
24
+ }
25
+ }
26
+ // Check if we are entering a new span
27
+ while (spanIdx < rowSpans.length && !inSpan) {
28
+ const next = rowSpans[spanIdx];
29
+ if (col >= next.col && col < next.col + next.len) {
30
+ result += colorForRole(theme, next.role);
31
+ inSpan = true;
32
+ break;
33
+ }
34
+ else if (col < next.col) {
35
+ break;
36
+ }
37
+ else {
38
+ spanIdx++;
39
+ }
40
+ }
41
+ result += art[col];
42
+ }
43
+ // Close any still-open span
44
+ if (inSpan) {
45
+ result += theme.reset;
46
+ }
47
+ return result;
48
+ }
49
+ // ── Span cache ──────────────────────────────────────────────────────
50
+ const spanCacheKey = Symbol('spansByRow');
51
+ function getSpansByRow(frame) {
52
+ const cached = frame[spanCacheKey];
53
+ if (cached)
54
+ return cached;
55
+ const map = new Map();
56
+ for (const span of frame.colors ?? []) {
57
+ let arr = map.get(span.row);
58
+ if (!arr) {
59
+ arr = [];
60
+ map.set(span.row, arr);
61
+ }
62
+ arr.push(span);
63
+ }
64
+ for (const arr of map.values()) {
65
+ arr.sort((a, b) => a.col - b.col);
66
+ }
67
+ frame[spanCacheKey] = map;
68
+ return map;
69
+ }
70
+ const EMPTY_SPANS = [];
71
+ // ── ANSI constants ──────────────────────────────────────────────────
72
+ const HIDE_CURSOR = '\x1b[?25l';
73
+ const SHOW_CURSOR = '\x1b[?25h';
74
+ const CURSOR_HOME = '\x1b[H';
75
+ const CLEAR_SCREEN = '\x1b[2J';
76
+ const DIM_ON = '\x1b[2m';
77
+ const DIM_OFF = '\x1b[0m';
78
+ const ALT_SCREEN_ON = '\x1b[?1049h';
79
+ const ALT_SCREEN_OFF = '\x1b[?1049l';
80
+ // ── FaceRenderer ────────────────────────────────────────────────────
81
+ const { minRenderIntervalMs: MIN_RENDER_INTERVAL_MS, transitionDurationMs: TRANSITION_DURATION_MS, transitionTickMs: TRANSITION_TICK_MS, sigmoidSteepness: SIGMOID_STEEPNESS, } = config;
82
+ export class FaceRenderer {
83
+ face;
84
+ theme;
85
+ currentState = 'idle';
86
+ currentFrameIndex = 0;
87
+ // Animation — self-throttling setTimeout with time-based frame selection.
88
+ animationTimer = null;
89
+ cycleStartTime = 0;
90
+ animCycleDuration = 0;
91
+ animForwardDuration = 0;
92
+ animFrameDuration = 0;
93
+ animFrameCount = 0;
94
+ animHasReverse = false;
95
+ animGapMin = 0;
96
+ animGapMax = 0;
97
+ animTickMs = MIN_RENDER_INTERVAL_MS;
98
+ // Render state
99
+ stdoutDraining = true;
100
+ hasRenderedOnce = false;
101
+ lastRenderedState = null;
102
+ lastRenderedFrame = -1;
103
+ // Pre-rendered frame cache stored as Buffers — avoids per-write UTF-8 encoding.
104
+ // Uses cursor-home + sequential rows instead of per-row cursor positioning,
105
+ // cutting ANSI escape sequences from ~40 per frame to 3.
106
+ frameCache = new Map();
107
+ clearScreenBuf = Buffer.alloc(0);
108
+ cachedCols = 0;
109
+ cachedRows = 0;
110
+ // Transition state — per-character flip with sigmoid-distributed timing.
111
+ transitioning = false;
112
+ transitionTimer = null;
113
+ transitionStartTime = 0;
114
+ transitionFlipTimes = null;
115
+ transitionOldArt = [];
116
+ transitionNewArt = [];
117
+ transitionOldRoles = [];
118
+ transitionNewRoles = [];
119
+ transitionNewState = 'idle';
120
+ constructor(face, theme) {
121
+ this.face = face;
122
+ this.theme = theme;
123
+ process.stdout.on('drain', () => {
124
+ this.stdoutDraining = true;
125
+ });
126
+ // Enter alternate screen buffer — prevents scrollback accumulation
127
+ process.stdout.write(ALT_SCREEN_ON + HIDE_CURSOR);
128
+ this.rebuildFrameCache();
129
+ }
130
+ // ── Pre-render all frames ───────────────────────────────────────
131
+ //
132
+ // Strategy: instead of 40 individual \x1b[row;1H cursor-position escapes
133
+ // per frame (expensive for terminal to parse), we use:
134
+ // \x1b[?25l — hide cursor (1 escape)
135
+ // \x1b[H — cursor home (1 escape)
136
+ // row\r\n — sequential rows with carriage-return + newline
137
+ // \x1b[2m — dim for status (1 escape)
138
+ //
139
+ // This cuts terminal escape parsing from ~40 per frame to ~3.
140
+ // Empty lines pad for vertical centering. Rows are clipped to terminal size.
141
+ rebuildFrameCache() {
142
+ const cols = process.stdout.columns ?? 80;
143
+ const rows = process.stdout.rows ?? 24;
144
+ this.cachedCols = cols;
145
+ this.cachedRows = rows;
146
+ this.frameCache.clear();
147
+ // Regenerate ASCII art at current terminal size if dynamic generation is available
148
+ if (hasDecodedFrames()) {
149
+ this.face = buildFace(cols, rows);
150
+ }
151
+ const hOffset = Math.max(0, Math.floor((cols - this.face.width) / 2));
152
+ const vOffset = Math.max(0, Math.floor((rows - this.face.height - 1) / 2));
153
+ const pad = ' '.repeat(hOffset);
154
+ const visibleArtWidth = Math.min(this.face.width, cols - hOffset);
155
+ const trailingPad = ' '.repeat(Math.max(0, cols - hOffset - visibleArtWidth));
156
+ const emptyLine = ' '.repeat(cols);
157
+ this.clearScreenBuf = Buffer.from(HIDE_CURSOR + CLEAR_SCREEN);
158
+ // How many art rows fit on screen (reserve 1 for status)
159
+ const maxArtRows = Math.max(0, rows - vOffset - 1);
160
+ for (const [stateName, expression] of Object.entries(this.face.expressions)) {
161
+ const expr = expression;
162
+ const rendered = [];
163
+ // Status line content
164
+ const statusPad = Math.max(0, Math.floor((cols - stateName.length) / 2));
165
+ const statusTrail = ' '.repeat(Math.max(0, cols - statusPad - stateName.length));
166
+ const statusContent = ' '.repeat(statusPad) + DIM_ON + stateName + DIM_OFF + statusTrail;
167
+ for (const frame of expr.frames) {
168
+ const spansByRow = getSpansByRow(frame);
169
+ const lines = [];
170
+ // Start with hide cursor + cursor home
171
+ lines.push(HIDE_CURSOR + CURSOR_HOME);
172
+ // Top padding (empty lines for vertical centering)
173
+ for (let i = 0; i < vOffset; i++) {
174
+ lines.push(emptyLine);
175
+ }
176
+ // Art rows (clipped to visible area)
177
+ const artRowCount = Math.min(frame.art.length, maxArtRows);
178
+ for (let r = 0; r < artRowCount; r++) {
179
+ const artRow = visibleArtWidth < frame.art[r].length
180
+ ? frame.art[r].slice(0, visibleArtWidth)
181
+ : frame.art[r];
182
+ const rowSpans = spansByRow.get(r) ?? EMPTY_SPANS;
183
+ const colored = renderRow(artRow, rowSpans, this.theme);
184
+ lines.push(pad + colored + trailingPad);
185
+ }
186
+ // Status line
187
+ lines.push(statusContent);
188
+ // Bottom padding (fill rest of screen to overwrite stale content)
189
+ // -1 because the escape-sequence element at lines[0] also produces a \r\n
190
+ const usedRows = vOffset + artRowCount + 1;
191
+ for (let i = usedRows; i < rows - 1; i++) {
192
+ lines.push(emptyLine);
193
+ }
194
+ // Join with \r\n and encode to Buffer once
195
+ rendered.push(Buffer.from(lines.join('\r\n')));
196
+ }
197
+ this.frameCache.set(stateName, rendered);
198
+ }
199
+ }
200
+ // ── Public API ──────────────────────────────────────────────────
201
+ setState(state) {
202
+ if (state === this.currentState && !this.transitioning && this.animationTimer !== null)
203
+ return;
204
+ // Capture where we're transitioning *from* before clearing state.
205
+ const fromState = this.transitioning ? this.transitionNewState : this.currentState;
206
+ const fromFrameIdx = this.transitioning ? 0 : this.currentFrameIndex;
207
+ this.stopAnimation();
208
+ this.stopTransition();
209
+ this.currentState = state;
210
+ this.currentFrameIndex = 0;
211
+ const expression = this.face.expressions[state];
212
+ if (!expression)
213
+ return;
214
+ // If we've already rendered and the state actually changed, transition.
215
+ if (this.hasRenderedOnce && fromState !== state) {
216
+ const fromExpr = this.face.expressions[fromState];
217
+ if (fromExpr) {
218
+ const oldFrame = fromExpr.frames[fromFrameIdx] ?? fromExpr.frames[0];
219
+ const newFrame = expression.frames[0];
220
+ this.beginTransition(oldFrame, newFrame, state);
221
+ return;
222
+ }
223
+ }
224
+ // First render or missing old expression — hard cut.
225
+ this.renderNow();
226
+ if (expression.frames.length > 1) {
227
+ this.startAnimation(expression);
228
+ }
229
+ }
230
+ invalidateCache() {
231
+ this.stopTransition();
232
+ this.rebuildFrameCache();
233
+ this.lastRenderedState = null;
234
+ this.lastRenderedFrame = -1;
235
+ this.renderNow();
236
+ }
237
+ showMessage(msg) {
238
+ // Stop any running animation/transition so they don't overwrite the message
239
+ this.stopAnimation();
240
+ this.stopTransition();
241
+ const cols = process.stdout.columns ?? 80;
242
+ const rows = process.stdout.rows ?? 24;
243
+ const hOffset = Math.max(0, Math.floor((cols - msg.length) / 2));
244
+ const vOffset = Math.max(0, Math.floor(rows / 2));
245
+ let out = HIDE_CURSOR + CLEAR_SCREEN;
246
+ out += `\x1b[${vOffset};1H`;
247
+ out += ' '.repeat(hOffset) + DIM_ON + msg + DIM_OFF;
248
+ process.stdout.write(out);
249
+ }
250
+ destroy() {
251
+ this.stopAnimation();
252
+ this.stopTransition();
253
+ // Leave alternate screen buffer and restore cursor
254
+ process.stdout.write(ALT_SCREEN_OFF + SHOW_CURSOR);
255
+ }
256
+ // ── Transition ─────────────────────────────────────────────────
257
+ buildRoleGrid(frame, artRows, artCols) {
258
+ const spansByRow = getSpansByRow(frame);
259
+ const grid = [];
260
+ for (let r = 0; r < artRows; r++) {
261
+ const row = new Array(artCols).fill(null);
262
+ const spans = spansByRow.get(r) ?? EMPTY_SPANS;
263
+ for (const span of spans) {
264
+ const end = Math.min(span.col + span.len, artCols);
265
+ for (let c = span.col; c < end; c++) {
266
+ row[c] = span.role;
267
+ }
268
+ }
269
+ grid.push(row);
270
+ }
271
+ return grid;
272
+ }
273
+ generateFlipTimes(totalPositions, duration) {
274
+ const times = new Float32Array(totalPositions);
275
+ const scale = duration / SIGMOID_STEEPNESS;
276
+ const half = duration / 2;
277
+ for (let i = 0; i < totalPositions; i++) {
278
+ // Uniform random in (0,1), clamped away from extremes to avoid ±Infinity
279
+ const u = 0.001 + Math.random() * 0.998;
280
+ // Logistic quantile — maps uniform distribution to sigmoid-shaped timing
281
+ times[i] = Math.max(0, Math.min(duration, half + scale * Math.log(u / (1 - u))));
282
+ }
283
+ return times;
284
+ }
285
+ beginTransition(oldFrame, newFrame, toState) {
286
+ const artRows = Math.max(oldFrame.art.length, newFrame.art.length);
287
+ const artCols = this.face.width;
288
+ this.transitionOldArt = oldFrame.art;
289
+ this.transitionNewArt = newFrame.art;
290
+ this.transitionOldRoles = this.buildRoleGrid(oldFrame, artRows, artCols);
291
+ this.transitionNewRoles = this.buildRoleGrid(newFrame, artRows, artCols);
292
+ this.transitionNewState = toState;
293
+ this.transitionFlipTimes = this.generateFlipTimes(artRows * artCols, TRANSITION_DURATION_MS);
294
+ this.transitionStartTime = Date.now();
295
+ this.transitioning = true;
296
+ // Invalidate so renderNow works after transition finishes
297
+ this.lastRenderedState = null;
298
+ this.lastRenderedFrame = -1;
299
+ this.renderTransitionFrame();
300
+ this.scheduleTransitionTick();
301
+ }
302
+ scheduleTransitionTick() {
303
+ this.transitionTimer = setTimeout(() => this.transitionTick(), TRANSITION_TICK_MS);
304
+ }
305
+ transitionTick() {
306
+ this.transitionTimer = null;
307
+ if (!this.transitioning)
308
+ return;
309
+ if (Date.now() - this.transitionStartTime >= TRANSITION_DURATION_MS) {
310
+ this.finishTransition();
311
+ return;
312
+ }
313
+ this.renderTransitionFrame();
314
+ this.scheduleTransitionTick();
315
+ }
316
+ finishTransition() {
317
+ this.transitioning = false;
318
+ this.transitionFlipTimes = null;
319
+ this.lastRenderedState = null;
320
+ this.lastRenderedFrame = -1;
321
+ this.renderNow();
322
+ const expression = this.face.expressions[this.currentState];
323
+ if (expression && expression.frames.length > 1) {
324
+ this.startAnimation(expression);
325
+ }
326
+ }
327
+ stopTransition() {
328
+ this.transitioning = false;
329
+ if (this.transitionTimer !== null) {
330
+ clearTimeout(this.transitionTimer);
331
+ this.transitionTimer = null;
332
+ }
333
+ this.transitionFlipTimes = null;
334
+ // Release transition art/role arrays to free memory immediately
335
+ this.transitionOldArt = [];
336
+ this.transitionNewArt = [];
337
+ this.transitionOldRoles = [];
338
+ this.transitionNewRoles = [];
339
+ }
340
+ renderTransitionFrame() {
341
+ if (!this.stdoutDraining)
342
+ return;
343
+ const cols = process.stdout.columns ?? 80;
344
+ const rows = process.stdout.rows ?? 24;
345
+ if (cols !== this.cachedCols || rows !== this.cachedRows) {
346
+ // Terminal resized mid-transition — snap to new state.
347
+ this.finishTransition();
348
+ return;
349
+ }
350
+ const elapsed = Date.now() - this.transitionStartTime;
351
+ const flipTimes = this.transitionFlipTimes;
352
+ const faceWidth = this.face.width;
353
+ const hOffset = Math.max(0, Math.floor((cols - faceWidth) / 2));
354
+ const vOffset = Math.max(0, Math.floor((rows - this.face.height - 1) / 2));
355
+ const pad = ' '.repeat(hOffset);
356
+ const visibleArtWidth = Math.min(faceWidth, cols - hOffset);
357
+ const trailingPad = ' '.repeat(Math.max(0, cols - hOffset - visibleArtWidth));
358
+ const emptyLine = ' '.repeat(cols);
359
+ const maxArtRows = Math.max(0, rows - vOffset - 1);
360
+ const artRowCount = Math.min(this.transitionOldArt.length, this.transitionNewArt.length, maxArtRows);
361
+ const lines = [];
362
+ lines.push(HIDE_CURSOR + CURSOR_HOME);
363
+ for (let i = 0; i < vOffset; i++) {
364
+ lines.push(emptyLine);
365
+ }
366
+ const artBuf = new Array(visibleArtWidth);
367
+ for (let r = 0; r < artRowCount; r++) {
368
+ // Build composite art string and color spans for this row.
369
+ const compositeSpans = [];
370
+ let currentRole = null;
371
+ let spanStart = 0;
372
+ for (let c = 0; c < visibleArtWidth; c++) {
373
+ const flipped = elapsed >= flipTimes[r * faceWidth + c];
374
+ artBuf[c] = flipped
375
+ ? (this.transitionNewArt[r]?.[c] ?? ' ')
376
+ : (this.transitionOldArt[r]?.[c] ?? ' ');
377
+ const role = flipped
378
+ ? (this.transitionNewRoles[r]?.[c] ?? null)
379
+ : (this.transitionOldRoles[r]?.[c] ?? null);
380
+ if (role !== currentRole) {
381
+ if (currentRole !== null) {
382
+ compositeSpans.push({ row: r, col: spanStart, len: c - spanStart, role: currentRole });
383
+ }
384
+ currentRole = role;
385
+ spanStart = c;
386
+ }
387
+ }
388
+ if (currentRole !== null) {
389
+ compositeSpans.push({ row: r, col: spanStart, len: visibleArtWidth - spanStart, role: currentRole });
390
+ }
391
+ const compositeArt = artBuf.join('');
392
+ const colored = renderRow(compositeArt, compositeSpans, this.theme);
393
+ lines.push(pad + colored + trailingPad);
394
+ }
395
+ // Status line — show the incoming state name
396
+ const stateName = this.transitionNewState;
397
+ const statusPad = Math.max(0, Math.floor((cols - stateName.length) / 2));
398
+ const statusTrail = ' '.repeat(Math.max(0, cols - statusPad - stateName.length));
399
+ lines.push(' '.repeat(statusPad) + DIM_ON + stateName + DIM_OFF + statusTrail);
400
+ const usedRows = vOffset + artRowCount + 1;
401
+ for (let i = usedRows; i < rows - 1; i++) {
402
+ lines.push(emptyLine);
403
+ }
404
+ this.stdoutDraining = process.stdout.write(Buffer.from(lines.join('\r\n')));
405
+ }
406
+ // ── Animation ───────────────────────────────────────────────────
407
+ startAnimation(expression) {
408
+ const config = expression.config;
409
+ const frameCount = expression.frames.length;
410
+ const frameDuration = config.loopDuration / frameCount;
411
+ const forwardDuration = config.loopDuration;
412
+ const reverseDuration = config.reverse ? config.loopDuration : 0;
413
+ this.animFrameCount = frameCount;
414
+ this.animFrameDuration = frameDuration;
415
+ this.animForwardDuration = forwardDuration;
416
+ this.animHasReverse = config.reverse;
417
+ this.animGapMin = config.gapMin ?? config.gap;
418
+ this.animGapMax = config.gapMax ?? config.gap;
419
+ this.animTickMs = Math.max(Math.round(frameDuration), MIN_RENDER_INTERVAL_MS);
420
+ this.startNewCycle();
421
+ this.scheduleNextTick();
422
+ }
423
+ startNewCycle() {
424
+ this.cycleStartTime = Date.now();
425
+ const gap = this.animGapMin + Math.random() * (this.animGapMax - this.animGapMin);
426
+ const reverseDuration = this.animHasReverse ? this.animForwardDuration : 0;
427
+ this.animCycleDuration = this.animForwardDuration + reverseDuration + gap;
428
+ }
429
+ scheduleNextTick() {
430
+ this.animationTimer = setTimeout(() => this.animationTick(), this.animTickMs);
431
+ }
432
+ animationTick() {
433
+ this.animationTimer = null;
434
+ const elapsed = Date.now() - this.cycleStartTime;
435
+ // If we've passed the end of this cycle, start a new one with a fresh random gap
436
+ if (elapsed >= this.animCycleDuration) {
437
+ this.startNewCycle();
438
+ }
439
+ const cyclePos = Date.now() - this.cycleStartTime;
440
+ let newFrame;
441
+ if (cyclePos < this.animForwardDuration) {
442
+ newFrame = Math.min(Math.floor(cyclePos / this.animFrameDuration), this.animFrameCount - 1);
443
+ }
444
+ else if (this.animHasReverse && cyclePos < this.animForwardDuration * 2) {
445
+ const revPos = cyclePos - this.animForwardDuration;
446
+ newFrame = Math.max(this.animFrameCount - 1 - Math.floor(revPos / this.animFrameDuration), 0);
447
+ }
448
+ else {
449
+ newFrame = 0;
450
+ }
451
+ if (newFrame !== this.currentFrameIndex) {
452
+ this.currentFrameIndex = newFrame;
453
+ this.renderNow();
454
+ }
455
+ this.scheduleNextTick();
456
+ }
457
+ stopAnimation() {
458
+ if (this.animationTimer !== null) {
459
+ clearTimeout(this.animationTimer);
460
+ this.animationTimer = null;
461
+ }
462
+ }
463
+ // ── Rendering ───────────────────────────────────────────────────
464
+ renderNow() {
465
+ if (!this.stdoutDraining)
466
+ return;
467
+ const cols = process.stdout.columns ?? 80;
468
+ const rows = process.stdout.rows ?? 24;
469
+ if (cols !== this.cachedCols || rows !== this.cachedRows) {
470
+ this.rebuildFrameCache();
471
+ }
472
+ if (this.lastRenderedState === this.currentState &&
473
+ this.lastRenderedFrame === this.currentFrameIndex) {
474
+ return;
475
+ }
476
+ const frames = this.frameCache.get(this.currentState);
477
+ if (!frames)
478
+ return;
479
+ const output = frames[this.currentFrameIndex];
480
+ if (!output)
481
+ return;
482
+ if (!this.hasRenderedOnce) {
483
+ this.stdoutDraining = process.stdout.write(Buffer.concat([this.clearScreenBuf, output]));
484
+ this.hasRenderedOnce = true;
485
+ }
486
+ else {
487
+ this.stdoutDraining = process.stdout.write(output);
488
+ }
489
+ this.lastRenderedState = this.currentState;
490
+ this.lastRenderedFrame = this.currentFrameIndex;
491
+ }
492
+ }
493
+ //# sourceMappingURL=face.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"face.js","sourceRoot":"","sources":["../../src/face.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare const defaultFace: import("./types.js").FaceDefinition;
@@ -0,0 +1,6 @@
1
+ import { initGenerator, buildFace } from './loader.js';
2
+ // Initialize generator (decode JPEGs) and build face at default width.
3
+ // The face will be rebuilt at actual terminal width by FaceRenderer on first render.
4
+ await initGenerator();
5
+ export const defaultFace = buildFace(process.stdout.columns ?? 100);
6
+ //# sourceMappingURL=frames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.js","sourceRoot":"","sources":["../../src/frames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEvD,uEAAuE;AACvE,qFAAqF;AACrF,MAAM,aAAa,EAAE,CAAC;AACtB,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Expression } from './types.js';
2
+ /**
3
+ * Decode all JPEGs from faces/{name}/img/ into grayscale pixel buffers.
4
+ * Called once at startup. Caches results in memory.
5
+ */
6
+ export declare function decodeAllFrames(facesDir: string, expressionNames: string[]): Promise<void>;
7
+ /**
8
+ * Generate ASCII frames for an expression at the given terminal width.
9
+ * Uses cached decoded pixel data — no disk I/O.
10
+ * @param maxRows - optional cap on art height (e.g. visible rows in terminal)
11
+ */
12
+ export declare function generateAsciiFrames(expressionName: string, targetWidth: number, maxRows?: number): Expression | null;
13
+ /**
14
+ * Check if decoded frames are available (sharp loaded + JPEGs decoded).
15
+ */
16
+ export declare function hasDecodedFrames(): boolean;