linecraft 0.1.0 → 0.2.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.
Files changed (283) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +313 -64
  3. package/lib/api/color.d.ts +6 -0
  4. package/lib/api/color.d.ts.map +1 -0
  5. package/lib/api/color.js +9 -0
  6. package/lib/api/color.js.map +1 -0
  7. package/lib/api/color.test.d.ts +2 -0
  8. package/lib/api/color.test.d.ts.map +1 -0
  9. package/lib/api/color.test.js +23 -0
  10. package/lib/api/color.test.js.map +1 -0
  11. package/lib/api/flex.d.ts +55 -0
  12. package/lib/api/flex.d.ts.map +1 -0
  13. package/lib/api/flex.js +86 -0
  14. package/lib/api/flex.js.map +1 -0
  15. package/lib/api/flex.test.d.ts +2 -0
  16. package/lib/api/flex.test.d.ts.map +1 -0
  17. package/lib/api/flex.test.js +82 -0
  18. package/lib/api/flex.test.js.map +1 -0
  19. package/lib/api/grid.d.ts +22 -0
  20. package/lib/api/grid.d.ts.map +1 -0
  21. package/lib/api/grid.js +65 -0
  22. package/lib/api/grid.js.map +1 -0
  23. package/lib/api/grid.test.d.ts +2 -0
  24. package/lib/api/grid.test.d.ts.map +1 -0
  25. package/lib/api/grid.test.js +48 -0
  26. package/lib/api/grid.test.js.map +1 -0
  27. package/lib/components/base.d.ts +53 -0
  28. package/lib/components/base.d.ts.map +1 -0
  29. package/lib/components/base.js +47 -0
  30. package/lib/components/base.js.map +1 -0
  31. package/lib/components/col.d.ts +35 -0
  32. package/lib/components/col.d.ts.map +1 -0
  33. package/lib/components/col.js +168 -0
  34. package/lib/components/col.js.map +1 -0
  35. package/lib/components/col.test.d.ts +2 -0
  36. package/lib/components/col.test.d.ts.map +1 -0
  37. package/lib/components/col.test.js +96 -0
  38. package/lib/components/col.test.js.map +1 -0
  39. package/lib/components/index.d.ts +3 -0
  40. package/lib/components/index.d.ts.map +1 -0
  41. package/lib/components/index.js +5 -0
  42. package/lib/components/index.js.map +1 -0
  43. package/lib/components/progress-bar-grid.d.ts +20 -0
  44. package/lib/components/progress-bar-grid.d.ts.map +1 -0
  45. package/lib/components/progress-bar-grid.js +44 -0
  46. package/lib/components/progress-bar-grid.js.map +1 -0
  47. package/lib/components/progress-bar-grid.test.d.ts +2 -0
  48. package/lib/components/progress-bar-grid.test.d.ts.map +1 -0
  49. package/lib/components/progress-bar-grid.test.js +101 -0
  50. package/lib/components/progress-bar-grid.test.js.map +1 -0
  51. package/lib/components/progress-bar.d.ts +26 -3
  52. package/lib/components/progress-bar.d.ts.map +1 -1
  53. package/lib/components/progress-bar.js +62 -6
  54. package/lib/components/progress-bar.js.map +1 -1
  55. package/lib/components/progress-bar.test.d.ts +2 -0
  56. package/lib/components/progress-bar.test.d.ts.map +1 -0
  57. package/lib/components/progress-bar.test.js +153 -0
  58. package/lib/components/progress-bar.test.js.map +1 -0
  59. package/lib/components/prompt.d.ts +14 -0
  60. package/lib/components/prompt.d.ts.map +1 -0
  61. package/lib/components/prompt.js +77 -0
  62. package/lib/components/prompt.js.map +1 -0
  63. package/lib/components/renderable.d.ts +42 -0
  64. package/lib/components/renderable.d.ts.map +1 -0
  65. package/lib/components/renderable.js +225 -0
  66. package/lib/components/renderable.js.map +1 -0
  67. package/lib/components/spinner.d.ts +2 -2
  68. package/lib/components/spinner.d.ts.map +1 -1
  69. package/lib/components/spinner.js +3 -1
  70. package/lib/components/spinner.js.map +1 -1
  71. package/lib/components/spinner.test.d.ts +2 -0
  72. package/lib/components/spinner.test.d.ts.map +1 -0
  73. package/lib/components/spinner.test.js +168 -0
  74. package/lib/components/spinner.test.js.map +1 -0
  75. package/lib/components/style.d.ts +16 -0
  76. package/lib/components/style.d.ts.map +1 -0
  77. package/lib/components/style.js +72 -0
  78. package/lib/components/style.js.map +1 -0
  79. package/lib/components/style.test.d.ts +2 -0
  80. package/lib/components/style.test.d.ts.map +1 -0
  81. package/lib/components/style.test.js +135 -0
  82. package/lib/components/style.test.js.map +1 -0
  83. package/lib/components/text.d.ts +24 -0
  84. package/lib/components/text.d.ts.map +1 -0
  85. package/lib/components/text.js +65 -0
  86. package/lib/components/text.js.map +1 -0
  87. package/lib/drawing/boxes.d.ts +33 -0
  88. package/lib/drawing/boxes.d.ts.map +1 -0
  89. package/lib/drawing/boxes.js +76 -0
  90. package/lib/drawing/boxes.js.map +1 -0
  91. package/lib/index.d.ts +18 -11
  92. package/lib/index.d.ts.map +1 -1
  93. package/lib/index.js +21 -10
  94. package/lib/index.js.map +1 -1
  95. package/lib/index.test.d.ts +2 -0
  96. package/lib/index.test.d.ts.map +1 -0
  97. package/lib/index.test.js +80 -0
  98. package/lib/index.test.js.map +1 -0
  99. package/lib/layout/flex.d.ts +39 -0
  100. package/lib/layout/flex.d.ts.map +1 -0
  101. package/lib/layout/flex.js +300 -0
  102. package/lib/layout/flex.js.map +1 -0
  103. package/lib/layout/flex.test.d.ts +2 -0
  104. package/lib/layout/flex.test.d.ts.map +1 -0
  105. package/lib/layout/flex.test.js +206 -0
  106. package/lib/layout/flex.test.js.map +1 -0
  107. package/lib/layout/grid.d.ts +53 -0
  108. package/lib/layout/grid.d.ts.map +1 -0
  109. package/lib/layout/grid.js +421 -0
  110. package/lib/layout/grid.js.map +1 -0
  111. package/lib/layout/grid.test.d.ts +2 -0
  112. package/lib/layout/grid.test.d.ts.map +1 -0
  113. package/lib/layout/grid.test.js +139 -0
  114. package/lib/layout/grid.test.js.map +1 -0
  115. package/lib/native/ansi.d.ts +104 -0
  116. package/lib/native/ansi.d.ts.map +1 -0
  117. package/lib/native/ansi.js +120 -0
  118. package/lib/native/ansi.js.map +1 -0
  119. package/lib/native/ansi.test.d.ts +2 -0
  120. package/lib/native/ansi.test.d.ts.map +1 -0
  121. package/lib/native/ansi.test.js +57 -0
  122. package/lib/native/ansi.test.js.map +1 -0
  123. package/lib/native/buffer.d.ts +32 -0
  124. package/lib/native/buffer.d.ts.map +1 -0
  125. package/lib/native/buffer.js +49 -0
  126. package/lib/native/buffer.js.map +1 -0
  127. package/lib/native/buffer.test.d.ts +2 -0
  128. package/lib/native/buffer.test.d.ts.map +1 -0
  129. package/lib/native/buffer.test.js +64 -0
  130. package/lib/native/buffer.test.js.map +1 -0
  131. package/lib/native/diff.d.ts +20 -0
  132. package/lib/native/diff.d.ts.map +1 -0
  133. package/lib/native/diff.js +33 -0
  134. package/lib/native/diff.js.map +1 -0
  135. package/lib/native/diff.test.d.ts +2 -0
  136. package/lib/native/diff.test.d.ts.map +1 -0
  137. package/lib/native/diff.test.js +106 -0
  138. package/lib/native/diff.test.js.map +1 -0
  139. package/lib/native/region-old.d.ts +117 -0
  140. package/lib/native/region-old.d.ts.map +1 -0
  141. package/lib/native/region-old.js +539 -0
  142. package/lib/native/region-old.js.map +1 -0
  143. package/lib/native/region-renderer.d.ts +167 -0
  144. package/lib/native/region-renderer.d.ts.map +1 -0
  145. package/lib/native/region-renderer.js +1238 -0
  146. package/lib/native/region-renderer.js.map +1 -0
  147. package/lib/native/region-simple.d.ts +44 -0
  148. package/lib/native/region-simple.d.ts.map +1 -0
  149. package/lib/native/region-simple.js +290 -0
  150. package/lib/native/region-simple.js.map +1 -0
  151. package/lib/native/region.d.ts +53 -0
  152. package/lib/native/region.d.ts.map +1 -0
  153. package/lib/native/region.js +426 -0
  154. package/lib/native/region.js.map +1 -0
  155. package/lib/native/region.test.d.ts +2 -0
  156. package/lib/native/region.test.d.ts.map +1 -0
  157. package/lib/native/region.test.js +248 -0
  158. package/lib/native/region.test.js.map +1 -0
  159. package/lib/native/throttle.d.ts +29 -0
  160. package/lib/native/throttle.d.ts.map +1 -0
  161. package/lib/native/throttle.js +57 -0
  162. package/lib/native/throttle.js.map +1 -0
  163. package/lib/native/throttle.test.d.ts +2 -0
  164. package/lib/native/throttle.test.d.ts.map +1 -0
  165. package/lib/native/throttle.test.js +86 -0
  166. package/lib/native/throttle.test.js.map +1 -0
  167. package/lib/native.d.ts +5 -11
  168. package/lib/native.d.ts.map +1 -1
  169. package/lib/native.js +8 -64
  170. package/lib/native.js.map +1 -1
  171. package/lib/region.d.ts +48 -5
  172. package/lib/region.d.ts.map +1 -1
  173. package/lib/region.js +474 -36
  174. package/lib/region.js.map +1 -1
  175. package/lib/region.test.d.ts +2 -0
  176. package/lib/region.test.d.ts.map +1 -0
  177. package/lib/region.test.js +227 -0
  178. package/lib/region.test.js.map +1 -0
  179. package/lib/region.visual.test.d.ts +2 -0
  180. package/lib/region.visual.test.d.ts.map +1 -0
  181. package/lib/region.visual.test.js +55 -0
  182. package/lib/region.visual.test.js.map +1 -0
  183. package/lib/test-helpers/capturable-terminal.d.ts +61 -0
  184. package/lib/test-helpers/capturable-terminal.d.ts.map +1 -0
  185. package/lib/test-helpers/capturable-terminal.js +113 -0
  186. package/lib/test-helpers/capturable-terminal.js.map +1 -0
  187. package/lib/test-helpers/capturable-terminal.test.d.ts +2 -0
  188. package/lib/test-helpers/capturable-terminal.test.d.ts.map +1 -0
  189. package/lib/test-helpers/capturable-terminal.test.js +45 -0
  190. package/lib/test-helpers/capturable-terminal.test.js.map +1 -0
  191. package/lib/test-helpers/mock-region.d.ts +21 -0
  192. package/lib/test-helpers/mock-region.d.ts.map +1 -0
  193. package/lib/test-helpers/mock-region.js +37 -0
  194. package/lib/test-helpers/mock-region.js.map +1 -0
  195. package/lib/test-helpers/virtual-terminal-diff-reflow.test.d.ts +2 -0
  196. package/lib/test-helpers/virtual-terminal-diff-reflow.test.d.ts.map +1 -0
  197. package/lib/test-helpers/virtual-terminal-diff-reflow.test.js +256 -0
  198. package/lib/test-helpers/virtual-terminal-diff-reflow.test.js.map +1 -0
  199. package/lib/test-helpers/virtual-terminal-flex-resize.test.d.ts +2 -0
  200. package/lib/test-helpers/virtual-terminal-flex-resize.test.d.ts.map +1 -0
  201. package/lib/test-helpers/virtual-terminal-flex-resize.test.js +438 -0
  202. package/lib/test-helpers/virtual-terminal-flex-resize.test.js.map +1 -0
  203. package/lib/test-helpers/virtual-terminal.d.ts +176 -0
  204. package/lib/test-helpers/virtual-terminal.d.ts.map +1 -0
  205. package/lib/test-helpers/virtual-terminal.js +492 -0
  206. package/lib/test-helpers/virtual-terminal.js.map +1 -0
  207. package/lib/test-helpers/virtual-terminal.test.d.ts +2 -0
  208. package/lib/test-helpers/virtual-terminal.test.d.ts.map +1 -0
  209. package/lib/test-helpers/virtual-terminal.test.js +219 -0
  210. package/lib/test-helpers/virtual-terminal.test.js.map +1 -0
  211. package/lib/ts/components/spinner.test.d.ts +2 -0
  212. package/lib/ts/components/spinner.test.d.ts.map +1 -0
  213. package/lib/ts/components/spinner.test.js +168 -0
  214. package/lib/ts/components/spinner.test.js.map +1 -0
  215. package/lib/ts/utils/colors.test.d.ts +2 -0
  216. package/lib/ts/utils/colors.test.d.ts.map +1 -0
  217. package/lib/ts/utils/colors.test.js +87 -0
  218. package/lib/ts/utils/colors.test.js.map +1 -0
  219. package/lib/types.d.ts +8 -2
  220. package/lib/types.d.ts.map +1 -1
  221. package/lib/types.js.map +1 -1
  222. package/lib/utils/colors-simple.d.ts +51 -0
  223. package/lib/utils/colors-simple.d.ts.map +1 -0
  224. package/lib/utils/colors-simple.js +59 -0
  225. package/lib/utils/colors-simple.js.map +1 -0
  226. package/lib/utils/colors.d.ts +1 -1
  227. package/lib/utils/colors.d.ts.map +1 -1
  228. package/lib/utils/colors.js.map +1 -1
  229. package/lib/utils/colors.test.d.ts +2 -0
  230. package/lib/utils/colors.test.d.ts.map +1 -0
  231. package/lib/utils/colors.test.js +87 -0
  232. package/lib/utils/colors.test.js.map +1 -0
  233. package/lib/utils/cursor-position.d.ts +22 -0
  234. package/lib/utils/cursor-position.d.ts.map +1 -0
  235. package/lib/utils/cursor-position.js +139 -0
  236. package/lib/utils/cursor-position.js.map +1 -0
  237. package/lib/utils/debug-log.d.ts +2 -0
  238. package/lib/utils/debug-log.d.ts.map +1 -0
  239. package/lib/utils/debug-log.js +36 -0
  240. package/lib/utils/debug-log.js.map +1 -0
  241. package/lib/utils/terminal.d.ts +27 -0
  242. package/lib/utils/terminal.d.ts.map +1 -0
  243. package/lib/utils/terminal.js +116 -0
  244. package/lib/utils/terminal.js.map +1 -0
  245. package/lib/utils/text.d.ts +21 -0
  246. package/lib/utils/text.d.ts.map +1 -0
  247. package/lib/utils/text.js +82 -0
  248. package/lib/utils/text.js.map +1 -0
  249. package/lib/utils/wait-for-spacebar.d.ts +10 -0
  250. package/lib/utils/wait-for-spacebar.d.ts.map +1 -0
  251. package/lib/utils/wait-for-spacebar.js +71 -0
  252. package/lib/utils/wait-for-spacebar.js.map +1 -0
  253. package/package.json +31 -28
  254. package/.cursor/plan.md +0 -952
  255. package/TESTING.md +0 -102
  256. package/build.zig +0 -100
  257. package/examples/basic-progress.ts +0 -21
  258. package/examples/multi-lane.ts +0 -29
  259. package/examples/spinner.ts +0 -20
  260. package/examples/test-basic.ts +0 -23
  261. package/src/ts/components/progress-bar.ts +0 -53
  262. package/src/ts/components/spinner.ts +0 -56
  263. package/src/ts/index.ts +0 -37
  264. package/src/ts/native.ts +0 -86
  265. package/src/ts/region.ts +0 -89
  266. package/src/ts/types/ffi-napi.d.ts +0 -11
  267. package/src/ts/types/ref-napi.d.ts +0 -5
  268. package/src/ts/types.ts +0 -53
  269. package/src/ts/utils/colors.ts +0 -72
  270. package/src/zig/ansi.zig +0 -21
  271. package/src/zig/buffer.zig +0 -37
  272. package/src/zig/diff.zig +0 -43
  273. package/src/zig/region.zig +0 -292
  274. package/src/zig/renderer.zig +0 -92
  275. package/src/zig/test_ansi.zig +0 -66
  276. package/src/zig/test_buffer.zig +0 -82
  277. package/src/zig/test_diff.zig +0 -220
  278. package/src/zig/test_integration.zig +0 -76
  279. package/src/zig/test_region.zig +0 -191
  280. package/src/zig/test_runner.zig +0 -27
  281. package/src/zig/test_throttle.zig +0 -59
  282. package/src/zig/throttle.zig +0 -38
  283. package/tsconfig.json +0 -21
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Test the VirtualTerminal itself
3
+ * These tests validate that VirtualTerminal behaves like a real terminal
4
+ */
5
+ import { describe, it, expect, beforeEach } from 'vitest';
6
+ import { VirtualTerminal } from './virtual-terminal.js';
7
+ import { TerminalRegion } from '../native/region.js';
8
+ describe('VirtualTerminal - Terminal Behavior Validation', () => {
9
+ let terminal;
10
+ beforeEach(() => {
11
+ terminal = new VirtualTerminal({ width: 80, height: 24 });
12
+ });
13
+ describe('Basic character tracking', () => {
14
+ it('should track character positions correctly', () => {
15
+ terminal.setLine(1, 'Hello');
16
+ expect(terminal.getCell(0, 0)?.char).toBe('H');
17
+ expect(terminal.getCell(1, 0)?.char).toBe('e');
18
+ expect(terminal.getCell(4, 0)?.char).toBe('o');
19
+ });
20
+ it('should preserve spaces in content', () => {
21
+ terminal.setLine(1, 'Hello World');
22
+ expect(terminal.getCell(5, 0)?.char).toBe(' ');
23
+ expect(terminal.getCell(6, 0)?.char).toBe('W');
24
+ });
25
+ });
26
+ describe('ANSI escape code handling', () => {
27
+ it('should parse and apply color codes', () => {
28
+ terminal.setLine(1, '\x1b[31mRed\x1b[0m');
29
+ expect(terminal.getCell(0, 0)?.fgColor).toBe('red');
30
+ expect(terminal.getCell(1, 0)?.fgColor).toBe('red');
31
+ expect(terminal.getCell(2, 0)?.fgColor).toBe('red');
32
+ expect(terminal.getCell(0, 0)?.char).toBe('R');
33
+ expect(terminal.getCell(1, 0)?.char).toBe('e');
34
+ expect(terminal.getCell(2, 0)?.char).toBe('d');
35
+ });
36
+ it('should reset colors with [0m', () => {
37
+ terminal.setLine(1, '\x1b[31mRed\x1b[0mNormal');
38
+ // After reset, color should be undefined (default)
39
+ const redEnd = terminal.getLine(1).indexOf('d') + 1;
40
+ // The "Normal" text should not have red color
41
+ // (We can't easily check this without ANSI, but we can verify the text is there)
42
+ expect(terminal.getLine(1)).toContain('Normal');
43
+ });
44
+ it('should handle bright colors', () => {
45
+ terminal.setLine(1, '\x1b[91mBrightRed\x1b[0m');
46
+ expect(terminal.getCell(0, 0)?.fgColor).toBe('brightRed');
47
+ });
48
+ it('should handle bold text', () => {
49
+ terminal.setLine(1, '\x1b[1mBold\x1b[0m');
50
+ expect(terminal.getCell(0, 0)?.bold).toBe(true);
51
+ });
52
+ });
53
+ describe('Text wrapping behavior (like real terminal)', () => {
54
+ it('should wrap text when content exceeds terminal width', () => {
55
+ // Create text longer than 80 columns
56
+ const longText = 'A'.repeat(100);
57
+ terminal.setLine(1, longText);
58
+ // First line should be full (80 chars)
59
+ expect(terminal.getCell(79, 0)?.char).toBe('A');
60
+ // Second line should have remaining characters (20 more)
61
+ expect(terminal.getCell(19, 1)?.char).toBe('A');
62
+ // Total should be 100 characters across 2 lines
63
+ const line1 = terminal.getLine(1);
64
+ const line2 = terminal.getLine(2);
65
+ const totalChars = line1.replace(/\s+$/, '').length + line2.replace(/\s+$/, '').length;
66
+ expect(totalChars).toBe(100);
67
+ });
68
+ it('should wrap at word boundaries when possible', () => {
69
+ // This is more complex - real terminals wrap at word boundaries
70
+ // For now, we wrap at exact width, but we can enhance this later
71
+ terminal.setLine(1, 'This is a long sentence that should wrap');
72
+ // With width 80, this should fit on one line
73
+ expect(terminal.getLine(1)).toContain('wrap');
74
+ });
75
+ it('should handle wrapping with ANSI codes', () => {
76
+ const coloredText = '\x1b[31m' + 'A'.repeat(100) + '\x1b[0m';
77
+ terminal.setLine(1, coloredText);
78
+ // First line should be red
79
+ expect(terminal.getCell(0, 0)?.fgColor).toBe('red');
80
+ expect(terminal.getCell(79, 0)?.fgColor).toBe('red');
81
+ // Second line should also be red (until reset)
82
+ expect(terminal.getCell(0, 1)?.fgColor).toBe('red');
83
+ });
84
+ });
85
+ describe('Resize and reflow behavior', () => {
86
+ it('should reflow text when terminal is resized narrower', () => {
87
+ // Write text that fits in 80 columns
88
+ terminal.setLine(1, 'Hello World');
89
+ expect(terminal.getLine(1)).toContain('Hello World');
90
+ // Resize to 20 columns (narrow but not too narrow)
91
+ terminal.simulateResize(20, 24);
92
+ // Text should still be on one line (fits in 20 chars)
93
+ const line1 = terminal.getLine(1);
94
+ expect(line1).toContain('Hello World');
95
+ // Note: The current resize reflow logic is position-based (copies cells),
96
+ // not text-based (reflows text). For a full text reflow, we'd need to:
97
+ // 1. Extract text from grid
98
+ // 2. Reflow based on new width
99
+ // 3. Write back to grid
100
+ // This is a complex feature that can be enhanced later.
101
+ // For now, verify that resize preserves what it can and emits events correctly.
102
+ });
103
+ it('should preserve content when resizing wider', () => {
104
+ terminal.setLine(1, 'Hello');
105
+ const originalContent = terminal.getLine(1);
106
+ // Resize wider
107
+ terminal.simulateResize(120, 24);
108
+ // Content should still be there
109
+ expect(terminal.getLine(1)).toContain('Hello');
110
+ });
111
+ it('should handle resize with multiple lines', () => {
112
+ terminal.setLine(1, 'Line 1: A'.repeat(10));
113
+ terminal.setLine(2, 'Line 2: B'.repeat(10));
114
+ terminal.setLine(3, 'Line 3: C'.repeat(10));
115
+ // Resize narrower
116
+ terminal.simulateResize(20, 24);
117
+ // All lines should still be accessible
118
+ expect(terminal.getLine(1)).toBeTruthy();
119
+ expect(terminal.getLine(2)).toBeTruthy();
120
+ expect(terminal.getLine(3)).toBeTruthy();
121
+ });
122
+ });
123
+ describe('Resize event integration with TerminalRegion', () => {
124
+ it('should emit resize events that native TerminalRegion can listen to', () => {
125
+ const writeStream = terminal.createWriteStream();
126
+ // Create region WITHOUT explicit width (enables auto-resize)
127
+ const region = new TerminalRegion({
128
+ height: 3,
129
+ stdout: writeStream,
130
+ disableRendering: false,
131
+ });
132
+ // Verify initial width (should match terminal)
133
+ expect(region.getWidth()).toBe(80);
134
+ // Resize the terminal
135
+ terminal.simulateResize(40, 24);
136
+ // The region should detect the resize and update its width
137
+ // Note: This happens synchronously via the event handler
138
+ expect(region.getWidth()).toBe(40);
139
+ region.destroy();
140
+ });
141
+ it('should NOT auto-resize when width is explicitly set', () => {
142
+ const writeStream = terminal.createWriteStream();
143
+ const region = new TerminalRegion({
144
+ width: 80, // Explicitly set
145
+ height: 3,
146
+ stdout: writeStream,
147
+ disableRendering: false,
148
+ });
149
+ expect(region.getWidth()).toBe(80);
150
+ // Resize terminal
151
+ terminal.simulateResize(40, 24);
152
+ // Width should NOT change (explicitly set)
153
+ expect(region.getWidth()).toBe(80);
154
+ region.destroy();
155
+ });
156
+ it('should work with TerminalRegion for full resize testing', () => {
157
+ const writeStream = terminal.createWriteStream();
158
+ const region = new TerminalRegion({
159
+ height: 3,
160
+ stdout: writeStream,
161
+ disableRendering: false, // Actually render to the virtual terminal
162
+ });
163
+ // Set some content
164
+ region.setLine(1, 'Line 1: This is a long line');
165
+ region.setLine(2, 'Line 2: Short');
166
+ region.setLine(3, 'Line 3: Another line');
167
+ region.flush(); // Force immediate render
168
+ // Note: The region writes ANSI codes for cursor movement, so we need to check
169
+ // the actual content. The virtual terminal should capture what was written.
170
+ // For now, just verify the region's internal state is correct
171
+ expect(region.getWidth()).toBe(80);
172
+ // Resize terminal to 20 columns (narrow)
173
+ terminal.simulateResize(20, 24);
174
+ // The region should update its width (auto-resize enabled)
175
+ expect(region.getWidth()).toBe(20);
176
+ expect(terminal.width).toBe(20);
177
+ region.destroy();
178
+ });
179
+ });
180
+ describe('Edge cases and real terminal behavior', () => {
181
+ it('should handle empty lines', () => {
182
+ terminal.setLine(1, '');
183
+ expect(terminal.getLine(1)).toBe('');
184
+ });
185
+ it('should handle lines with only spaces', () => {
186
+ terminal.setLine(1, ' ');
187
+ const line = terminal.getLine(1);
188
+ // getLine trims trailing spaces, so a line with only spaces returns empty
189
+ expect(line).toBe('');
190
+ });
191
+ it('should handle carriage return (\\r)', () => {
192
+ terminal.setLine(1, 'Hello\rWorld');
193
+ // \r should move cursor to start, so "World" overwrites "Hello"
194
+ expect(terminal.getLine(1)).toContain('World');
195
+ expect(terminal.getLine(1)).not.toContain('Hello');
196
+ });
197
+ it('should handle newline (\\n) in content', () => {
198
+ terminal.setLine(1, 'Line1\nLine2');
199
+ // setLine should handle this, but if we write directly, \n should create new line
200
+ expect(terminal.getLine(1)).toBeTruthy();
201
+ expect(terminal.getLine(2)).toBeTruthy();
202
+ });
203
+ it('should handle very long lines (stress test)', () => {
204
+ const veryLongText = 'A'.repeat(1000);
205
+ terminal.setLine(1, veryLongText);
206
+ // Should wrap to multiple lines
207
+ const lineCount = Math.ceil(1000 / 80);
208
+ expect(terminal.getLine(lineCount)).toBeTruthy();
209
+ });
210
+ it('should handle rapid resize events', () => {
211
+ terminal.simulateResize(40, 24);
212
+ terminal.simulateResize(80, 24);
213
+ terminal.simulateResize(20, 24);
214
+ expect(terminal.width).toBe(20);
215
+ expect(terminal.height).toBe(24);
216
+ });
217
+ });
218
+ });
219
+ //# sourceMappingURL=virtual-terminal.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-terminal.test.js","sourceRoot":"","sources":["../../src/ts/test-helpers/virtual-terminal.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spinner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.test.d.ts","sourceRoot":"","sources":["../../../src/ts/components/spinner.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,168 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { Spinner } from './spinner';
3
+ // Mock the region
4
+ const createMockRegion = () => {
5
+ const setLineMock = vi.fn();
6
+ const mockRegion = {
7
+ setLine: setLineMock,
8
+ };
9
+ return { region: mockRegion, setLineMock };
10
+ };
11
+ describe('Spinner', () => {
12
+ let region;
13
+ let setLineMock;
14
+ let spinner;
15
+ beforeEach(() => {
16
+ vi.useFakeTimers();
17
+ const mock = createMockRegion();
18
+ region = mock.region;
19
+ setLineMock = mock.setLineMock;
20
+ });
21
+ afterEach(() => {
22
+ if (spinner) {
23
+ spinner.stop();
24
+ }
25
+ vi.useRealTimers();
26
+ vi.clearAllMocks();
27
+ });
28
+ describe('constructor', () => {
29
+ it('should create a spinner with default options', () => {
30
+ spinner = new Spinner(region, 1);
31
+ expect(spinner).toBeDefined();
32
+ });
33
+ it('should create a spinner with custom frames', () => {
34
+ const customFrames = ['-', '\\', '|', '/'];
35
+ spinner = new Spinner(region, 1, { frames: customFrames });
36
+ expect(spinner).toBeDefined();
37
+ });
38
+ it('should create a spinner with custom interval', () => {
39
+ spinner = new Spinner(region, 1, { interval: 200 });
40
+ expect(spinner).toBeDefined();
41
+ });
42
+ });
43
+ describe('start', () => {
44
+ it('should start the spinner and begin rendering', () => {
45
+ spinner = new Spinner(region, 1);
46
+ spinner.start();
47
+ expect(setLineMock).toHaveBeenCalled();
48
+ });
49
+ it('should not start multiple times if already running', () => {
50
+ spinner = new Spinner(region, 1);
51
+ spinner.start();
52
+ const callCount1 = setLineMock.mock.calls.length;
53
+ spinner.start();
54
+ const callCount2 = setLineMock.mock.calls.length;
55
+ expect(callCount2).toBe(callCount1);
56
+ });
57
+ it('should advance frames on interval', () => {
58
+ spinner = new Spinner(region, 1, { interval: 100 });
59
+ spinner.start();
60
+ const firstCall = setLineMock.mock.calls[0];
61
+ const firstFrame = firstCall[1];
62
+ vi.advanceTimersByTime(100);
63
+ expect(setLineMock).toHaveBeenCalledTimes(2);
64
+ const secondCall = setLineMock.mock.calls[1];
65
+ const secondFrame = secondCall[1];
66
+ // Frames should be different
67
+ expect(firstFrame).not.toBe(secondFrame);
68
+ });
69
+ it('should cycle through all frames', () => {
70
+ const frames = ['A', 'B', 'C'];
71
+ spinner = new Spinner(region, 1, { frames, interval: 100 });
72
+ spinner.start();
73
+ const seenFrames = [];
74
+ for (let i = 0; i < frames.length; i++) {
75
+ vi.advanceTimersByTime(100);
76
+ const call = setLineMock.mock.calls[i];
77
+ const content = typeof call[1] === 'string' ? call[1] : call[1].text;
78
+ seenFrames.push(content.charAt(0));
79
+ }
80
+ // Should have seen all frames
81
+ expect(seenFrames).toContain('A');
82
+ expect(seenFrames).toContain('B');
83
+ expect(seenFrames).toContain('C');
84
+ });
85
+ });
86
+ describe('stop', () => {
87
+ it('should stop the spinner', () => {
88
+ spinner = new Spinner(region, 1);
89
+ spinner.start();
90
+ spinner.stop();
91
+ // Clear the interval
92
+ vi.advanceTimersByTime(200);
93
+ // Should have cleared the line
94
+ const calls = setLineMock.mock.calls;
95
+ const lastCall = calls[calls.length - 1];
96
+ expect(lastCall[1]).toBe('');
97
+ });
98
+ it('should not stop if not running', () => {
99
+ spinner = new Spinner(region, 1);
100
+ spinner.stop();
101
+ spinner.stop(); // Should not throw
102
+ });
103
+ it('should clear the spinner line when stopped', () => {
104
+ spinner = new Spinner(region, 1);
105
+ spinner.start();
106
+ spinner.stop();
107
+ const calls = setLineMock.mock.calls;
108
+ const lastCall = calls[calls.length - 1];
109
+ expect(lastCall[1]).toBe('');
110
+ });
111
+ });
112
+ describe('setText', () => {
113
+ it('should update text and render', () => {
114
+ spinner = new Spinner(region, 1);
115
+ spinner.setText('Loading...');
116
+ expect(setLineMock).toHaveBeenCalled();
117
+ const call = setLineMock.mock.calls[0];
118
+ const content = typeof call[1] === 'string' ? call[1] : call[1].text;
119
+ expect(content).toContain('Loading...');
120
+ });
121
+ it('should update text while running', () => {
122
+ spinner = new Spinner(region, 1);
123
+ spinner.start();
124
+ spinner.setText('Processing...');
125
+ const calls = setLineMock.mock.calls;
126
+ const lastCall = calls[calls.length - 1];
127
+ const content = typeof lastCall[1] === 'string' ? lastCall[1] : lastCall[1].text;
128
+ expect(content).toContain('Processing...');
129
+ });
130
+ it('should preserve text when frame advances', () => {
131
+ spinner = new Spinner(region, 1, { interval: 100 });
132
+ spinner.setText('Working');
133
+ spinner.start();
134
+ vi.advanceTimersByTime(100);
135
+ const calls = setLineMock.mock.calls;
136
+ const lastCall = calls[calls.length - 1];
137
+ const content = typeof lastCall[1] === 'string' ? lastCall[1] : lastCall[1].text;
138
+ expect(content).toContain('Working');
139
+ });
140
+ });
141
+ describe('custom frames', () => {
142
+ it('should use custom frames', () => {
143
+ const customFrames = ['-', '\\', '|', '/'];
144
+ spinner = new Spinner(region, 1, { frames: customFrames, interval: 100 });
145
+ spinner.start();
146
+ const firstCall = setLineMock.mock.calls[0];
147
+ const content = typeof firstCall[1] === 'string' ? firstCall[1] : firstCall[1].text;
148
+ const firstChar = content.charAt(0);
149
+ expect(customFrames).toContain(firstChar);
150
+ });
151
+ });
152
+ describe('custom interval', () => {
153
+ it('should use custom interval', () => {
154
+ spinner = new Spinner(region, 1, { interval: 200 });
155
+ spinner.start();
156
+ const callCount1 = setLineMock.mock.calls.length;
157
+ vi.advanceTimersByTime(100);
158
+ const callCount2 = setLineMock.mock.calls.length;
159
+ // Should not have advanced yet
160
+ expect(callCount2).toBe(callCount1);
161
+ vi.advanceTimersByTime(100);
162
+ const callCount3 = setLineMock.mock.calls.length;
163
+ // Should have advanced now
164
+ expect(callCount3).toBeGreaterThan(callCount2);
165
+ });
166
+ });
167
+ });
168
+ //# sourceMappingURL=spinner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.test.js","sourceRoot":"","sources":["../../../src/ts/components/spinner.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=colors.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.test.d.ts","sourceRoot":"","sources":["../../../src/ts/utils/colors.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,87 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { applyStyle } from './colors';
3
+ describe('applyStyle', () => {
4
+ it('should return text unchanged when no style is provided', () => {
5
+ const text = 'Hello, World!';
6
+ expect(applyStyle(text)).toBe(text);
7
+ expect(applyStyle(text, undefined)).toBe(text);
8
+ });
9
+ it('should apply foreground color', () => {
10
+ const text = 'Red text';
11
+ const styled = applyStyle(text, { color: 'red' });
12
+ expect(styled).toContain('\x1b[');
13
+ expect(styled).toContain('31'); // ANSI code for red
14
+ expect(styled).toContain('m');
15
+ expect(styled).toContain(text);
16
+ expect(styled).toContain('\x1b[0m'); // Reset
17
+ });
18
+ it('should apply background color', () => {
19
+ const text = 'Blue background';
20
+ const styled = applyStyle(text, { backgroundColor: 'blue' });
21
+ expect(styled).toContain('44'); // ANSI code for blue background
22
+ expect(styled).toContain(text);
23
+ });
24
+ it('should apply bold style', () => {
25
+ const text = 'Bold text';
26
+ const styled = applyStyle(text, { bold: true });
27
+ expect(styled).toContain('1'); // ANSI code for bold
28
+ expect(styled).toContain(text);
29
+ });
30
+ it('should apply italic style', () => {
31
+ const text = 'Italic text';
32
+ const styled = applyStyle(text, { italic: true });
33
+ expect(styled).toContain('3'); // ANSI code for italic
34
+ expect(styled).toContain(text);
35
+ });
36
+ it('should apply underline style', () => {
37
+ const text = 'Underlined text';
38
+ const styled = applyStyle(text, { underline: true });
39
+ expect(styled).toContain('4'); // ANSI code for underline
40
+ expect(styled).toContain(text);
41
+ });
42
+ it('should apply multiple styles', () => {
43
+ const text = 'Styled text';
44
+ const styled = applyStyle(text, {
45
+ color: 'green',
46
+ backgroundColor: 'yellow',
47
+ bold: true,
48
+ italic: true,
49
+ underline: true,
50
+ });
51
+ expect(styled).toContain('32'); // green
52
+ expect(styled).toContain('43'); // yellow background
53
+ expect(styled).toContain('1'); // bold
54
+ expect(styled).toContain('3'); // italic
55
+ expect(styled).toContain('4'); // underline
56
+ expect(styled).toContain(text);
57
+ expect(styled).toContain('\x1b[0m'); // Reset at end
58
+ });
59
+ it('should handle all color values', () => {
60
+ const colors = [
61
+ 'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white',
62
+ ];
63
+ colors.forEach(color => {
64
+ const styled = applyStyle('test', { color });
65
+ expect(styled).toContain('\x1b[');
66
+ expect(styled).toContain('m');
67
+ });
68
+ });
69
+ it('should handle bright colors', () => {
70
+ const styled = applyStyle('test', { color: 'brightRed' });
71
+ expect(styled).toContain('91'); // ANSI code for bright red
72
+ });
73
+ it('should handle bright background colors', () => {
74
+ const styled = applyStyle('test', { backgroundColor: 'brightBlue' });
75
+ expect(styled).toContain('104'); // ANSI code for bright blue background
76
+ });
77
+ it('should properly format ANSI escape sequences', () => {
78
+ const styled = applyStyle('test', { color: 'red', bold: true });
79
+ // Should be: \x1b[31;1mtest\x1b[0m
80
+ expect(styled).toMatch(/^\x1b\[31;1mtest\x1b\[0m$/);
81
+ });
82
+ it('should reset styles at the end', () => {
83
+ const styled = applyStyle('test', { color: 'blue' });
84
+ expect(styled.endsWith('\x1b[0m')).toBe(true);
85
+ });
86
+ });
87
+ //# sourceMappingURL=colors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.test.js","sourceRoot":"","sources":["../../../src/ts/utils/colors.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,IAAI,GAAG,eAAe,CAAC;QAC7B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,UAAU,CAAC;QACxB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,iBAAiB,CAAC;QAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,gCAAgC;QAChE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,IAAI,GAAG,WAAW,CAAC;QACzB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,qBAAqB;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,IAAI,GAAG,aAAa,CAAC;QAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,uBAAuB;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,IAAI,GAAG,iBAAiB,CAAC;QAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,0BAA0B;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,IAAI,GAAG,aAAa,CAAC;QAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE;YAC9B,KAAK,EAAE,OAAO;YACd,eAAe,EAAE,QAAQ;YACzB,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAwF;YAClG,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO;SACtE,CAAC;QAEF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACrB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,2BAA2B;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,uCAAuC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,mCAAmC;QACnC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/lib/types.d.ts CHANGED
@@ -11,10 +11,10 @@ export interface LineContent {
11
11
  style?: TextStyle;
12
12
  }
13
13
  export interface RegionOptions {
14
- x?: number;
15
- y?: number;
16
14
  width?: number;
17
15
  height?: number;
16
+ stdout?: NodeJS.WriteStream;
17
+ disableRendering?: boolean;
18
18
  }
19
19
  export interface ProgressBarOptions {
20
20
  label?: string;
@@ -29,4 +29,10 @@ export interface SpinnerOptions {
29
29
  frames?: string[];
30
30
  interval?: number;
31
31
  }
32
+ /**
33
+ * Base options for all components - includes common styling props
34
+ */
35
+ export interface BaseComponentOptions {
36
+ color?: Color;
37
+ }
32
38
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/ts/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GACb,OAAO,GACP,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,MAAM,GACN,OAAO,GACP,aAAa,GACb,WAAW,GACX,aAAa,GACb,cAAc,GACd,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,aAAa,CAAC;AAElB,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,eAAe,CAAC,EAAE,KAAK,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GACb,OAAO,GACP,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,MAAM,GACN,OAAO,GACP,aAAa,GACb,WAAW,GACX,aAAa,GACb,cAAc,GACd,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,aAAa,CAAC;AAElB,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,eAAe,CAAC,EAAE,KAAK,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf"}
package/lib/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/ts/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ import type { Color } from '../types';
2
+ /**
3
+ * Simple color formatting using template-like syntax
4
+ * Example: color`Hello ${'world'}.red.bold`
5
+ */
6
+ export declare function color(strings: TemplateStringsArray, ...values: any[]): string;
7
+ /**
8
+ * Create a color formatter function
9
+ * Usage: const red = colorFn('red', { bold: true });
10
+ * red('Hello') // returns styled text
11
+ */
12
+ export declare function colorFn(color: Color, style?: {
13
+ bold?: boolean;
14
+ italic?: boolean;
15
+ underline?: boolean;
16
+ }): (text: string) => string;
17
+ /**
18
+ * Pre-defined color formatters for convenience
19
+ */
20
+ export declare const colors: {
21
+ black: (text: string) => string;
22
+ red: (text: string) => string;
23
+ green: (text: string) => string;
24
+ yellow: (text: string) => string;
25
+ blue: (text: string) => string;
26
+ magenta: (text: string) => string;
27
+ cyan: (text: string) => string;
28
+ white: (text: string) => string;
29
+ brightBlack: (text: string) => string;
30
+ brightRed: (text: string) => string;
31
+ brightGreen: (text: string) => string;
32
+ brightYellow: (text: string) => string;
33
+ brightBlue: (text: string) => string;
34
+ brightMagenta: (text: string) => string;
35
+ brightCyan: (text: string) => string;
36
+ brightWhite: (text: string) => string;
37
+ bold: (text: string) => string;
38
+ dim: (text: string) => string;
39
+ italic: (text: string) => string;
40
+ underline: (text: string) => string;
41
+ };
42
+ /**
43
+ * Chainable color API
44
+ * Usage: colors.red.bold('Hello') or colors.bold.red('Hello')
45
+ */
46
+ type ColorChain = {
47
+ [K in keyof typeof colors]: ColorChain & ((text: string) => string);
48
+ };
49
+ export declare const c: ColorChain;
50
+ export {};
51
+ //# sourceMappingURL=colors-simple.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors-simple.d.ts","sourceRoot":"","sources":["../../src/utils/colors-simple.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC;;;GAGG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAS7E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAEjI;AAED;;GAEG;AACH,eAAO,MAAM,MAAM;kBACH,MAAM;gBACR,MAAM;kBACJ,MAAM;mBACL,MAAM;iBACR,MAAM;oBACH,MAAM;iBACT,MAAM;kBACL,MAAM;wBACA,MAAM;sBACR,MAAM;wBACJ,MAAM;yBACL,MAAM;uBACR,MAAM;0BACH,MAAM;uBACT,MAAM;wBACL,MAAM;iBACb,MAAM;gBACP,MAAM;mBACH,MAAM;sBACH,MAAM;CACzB,CAAC;AAEF;;;GAGG;AACH,KAAK,UAAU,GAAG;KACf,CAAC,IAAI,MAAM,OAAO,MAAM,GAAG,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACpE,CAAC;AAaF,eAAO,MAAM,CAAC,YAAqB,CAAC"}