termcast 1.4.1 → 1.5.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 (140) hide show
  1. package/dist/build.d.ts.map +1 -1
  2. package/dist/build.js +8 -7
  3. package/dist/build.js.map +1 -1
  4. package/dist/cli.js +0 -40
  5. package/dist/cli.js.map +1 -1
  6. package/dist/components/bar-graph.d.ts +23 -8
  7. package/dist/components/bar-graph.d.ts.map +1 -1
  8. package/dist/components/bar-graph.js +84 -40
  9. package/dist/components/bar-graph.js.map +1 -1
  10. package/dist/components/dotted-line-graph.d.ts +86 -0
  11. package/dist/components/dotted-line-graph.d.ts.map +1 -0
  12. package/dist/components/dotted-line-graph.js +260 -0
  13. package/dist/components/dotted-line-graph.js.map +1 -0
  14. package/dist/components/extension-preferences.d.ts.map +1 -1
  15. package/dist/components/extension-preferences.js +1 -10
  16. package/dist/components/extension-preferences.js.map +1 -1
  17. package/dist/components/graph.d.ts.map +1 -1
  18. package/dist/components/graph.js +7 -1
  19. package/dist/components/graph.js.map +1 -1
  20. package/dist/components/histogram.d.ts +42 -0
  21. package/dist/components/histogram.d.ts.map +1 -0
  22. package/dist/components/histogram.js +115 -0
  23. package/dist/components/histogram.js.map +1 -0
  24. package/dist/components/horizontal-bar-graph.d.ts +47 -0
  25. package/dist/components/horizontal-bar-graph.d.ts.map +1 -0
  26. package/dist/components/horizontal-bar-graph.js +137 -0
  27. package/dist/components/horizontal-bar-graph.js.map +1 -0
  28. package/dist/components/list.d.ts +2 -0
  29. package/dist/components/list.d.ts.map +1 -1
  30. package/dist/components/list.js +10 -10
  31. package/dist/components/list.js.map +1 -1
  32. package/dist/examples/bar-graph-weekly.js +2 -2
  33. package/dist/examples/bar-graph-weekly.js.map +1 -1
  34. package/dist/examples/charts-showcase-barchart.d.ts +2 -0
  35. package/dist/examples/charts-showcase-barchart.d.ts.map +1 -0
  36. package/dist/examples/charts-showcase-barchart.js +10 -0
  37. package/dist/examples/charts-showcase-barchart.js.map +1 -0
  38. package/dist/examples/charts-showcase-bargraph.d.ts +2 -0
  39. package/dist/examples/charts-showcase-bargraph.d.ts.map +1 -0
  40. package/dist/examples/charts-showcase-bargraph.js +60 -0
  41. package/dist/examples/charts-showcase-bargraph.js.map +1 -0
  42. package/dist/examples/charts-showcase-candle.d.ts +2 -0
  43. package/dist/examples/charts-showcase-candle.d.ts.map +1 -0
  44. package/dist/examples/charts-showcase-candle.js +30 -0
  45. package/dist/examples/charts-showcase-candle.js.map +1 -0
  46. package/dist/examples/charts-showcase-graph.d.ts +2 -0
  47. package/dist/examples/charts-showcase-graph.d.ts.map +1 -0
  48. package/dist/examples/charts-showcase-graph.js +33 -0
  49. package/dist/examples/charts-showcase-graph.js.map +1 -0
  50. package/dist/examples/charts-showcase-heatmap.d.ts +2 -0
  51. package/dist/examples/charts-showcase-heatmap.d.ts.map +1 -0
  52. package/dist/examples/charts-showcase-heatmap.js +36 -0
  53. package/dist/examples/charts-showcase-heatmap.js.map +1 -0
  54. package/dist/examples/charts-showcase-mixed.d.ts +2 -0
  55. package/dist/examples/charts-showcase-mixed.d.ts.map +1 -0
  56. package/dist/examples/charts-showcase-mixed.js +30 -0
  57. package/dist/examples/charts-showcase-mixed.js.map +1 -0
  58. package/dist/examples/charts-showcase-progress.d.ts +2 -0
  59. package/dist/examples/charts-showcase-progress.d.ts.map +1 -0
  60. package/dist/examples/charts-showcase-progress.js +10 -0
  61. package/dist/examples/charts-showcase-progress.js.map +1 -0
  62. package/dist/examples/graph-multi-series.js +1 -1
  63. package/dist/examples/graph-multi-series.js.map +1 -1
  64. package/dist/examples/horizontal-bar-graph-weekly.d.ts +2 -0
  65. package/dist/examples/horizontal-bar-graph-weekly.d.ts.map +1 -0
  66. package/dist/examples/horizontal-bar-graph-weekly.js +67 -0
  67. package/dist/examples/horizontal-bar-graph-weekly.js.map +1 -0
  68. package/dist/examples/simple-dotted-line-graph.d.ts +2 -0
  69. package/dist/examples/simple-dotted-line-graph.d.ts.map +1 -0
  70. package/dist/examples/simple-dotted-line-graph.js +39 -0
  71. package/dist/examples/simple-dotted-line-graph.js.map +1 -0
  72. package/dist/examples/simple-histogram.d.ts +2 -0
  73. package/dist/examples/simple-histogram.d.ts.map +1 -0
  74. package/dist/examples/simple-histogram.js +47 -0
  75. package/dist/examples/simple-histogram.js.map +1 -0
  76. package/dist/index.d.ts +6 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +6 -0
  79. package/dist/index.js.map +1 -1
  80. package/dist/platform/node/sqlite.d.ts +6 -5
  81. package/dist/platform/node/sqlite.d.ts.map +1 -1
  82. package/dist/platform/node/sqlite.js +30 -14
  83. package/dist/platform/node/sqlite.js.map +1 -1
  84. package/dist/theme.d.ts.map +1 -1
  85. package/dist/theme.js +11 -9
  86. package/dist/theme.js.map +1 -1
  87. package/dist/utils/run-command.d.ts.map +1 -1
  88. package/dist/utils/run-command.js +8 -19
  89. package/dist/utils/run-command.js.map +1 -1
  90. package/dist/utils.d.ts +1 -19
  91. package/dist/utils.d.ts.map +1 -1
  92. package/dist/utils.js +1 -100
  93. package/dist/utils.js.map +1 -1
  94. package/package.json +6 -8
  95. package/src/build.tsx +11 -10
  96. package/src/cli.tsx +3 -40
  97. package/src/compile.vitest.tsx +3 -3
  98. package/src/components/bar-graph.tsx +217 -111
  99. package/src/components/dotted-line-graph.tsx +407 -0
  100. package/src/components/extension-preferences.tsx +2 -12
  101. package/src/components/graph.tsx +5 -1
  102. package/src/components/histogram.tsx +228 -0
  103. package/src/components/horizontal-bar-graph.tsx +279 -0
  104. package/src/components/list.tsx +20 -15
  105. package/src/examples/action-shortcut.vitest.tsx +17 -17
  106. package/src/examples/bar-graph-weekly.tsx +2 -2
  107. package/src/examples/bar-graph-weekly.vitest.tsx +63 -62
  108. package/src/examples/charts-showcase-bargraph.tsx +103 -0
  109. package/src/examples/detail-metadata-showcase.vitest.tsx +12 -12
  110. package/src/examples/form-basic.vitest.tsx +11 -11
  111. package/src/examples/form-dropdown.vitest.tsx +11 -11
  112. package/src/examples/form-scroll.vitest.tsx +1 -1
  113. package/src/examples/form-tagpicker.vitest.tsx +11 -11
  114. package/src/examples/github.vitest.tsx +22 -22
  115. package/src/examples/graph-bar-chart.vitest.tsx +8 -8
  116. package/src/examples/graph-multi-series.tsx +1 -1
  117. package/src/examples/graph-row.vitest.tsx +14 -14
  118. package/src/examples/graph-styles.vitest.tsx +77 -77
  119. package/src/examples/horizontal-bar-graph-weekly.tsx +138 -0
  120. package/src/examples/horizontal-bar-graph-weekly.vitest.tsx +164 -0
  121. package/src/examples/list-detail-metadata.vitest.tsx +4 -4
  122. package/src/examples/list-with-detail.vitest.tsx +46 -46
  123. package/src/examples/simple-candle-chart.vitest.tsx +8 -8
  124. package/src/examples/simple-dotted-line-graph.tsx +53 -0
  125. package/src/examples/simple-dotted-line-graph.vitest.tsx +62 -0
  126. package/src/examples/simple-grid.vitest.tsx +4 -4
  127. package/src/examples/simple-heatmap.vitest.tsx +9 -9
  128. package/src/examples/simple-histogram.tsx +90 -0
  129. package/src/examples/simple-navigation.vitest.tsx +4 -4
  130. package/src/examples/swift-extension.vitest.tsx +3 -3
  131. package/src/extensions/dev.vitest.tsx +8 -8
  132. package/src/index.tsx +21 -0
  133. package/src/platform/node/sqlite.ts +29 -13
  134. package/src/theme.tsx +11 -10
  135. package/src/utils/run-command.tsx +10 -19
  136. package/src/utils.tsx +0 -163
  137. package/src/examples/store.tsx +0 -4
  138. package/src/examples/store.vitest.tsx +0 -78
  139. package/src/extensions/home.tsx +0 -227
  140. package/src/extensions/store.tsx +0 -375
@@ -80,13 +80,11 @@ test('list with detail view display and navigation', async () => {
80
80
  > Search Pokemon...
81
81
 
82
82
  bulbasaur #001 │ ivysaur ▲
83
- ›ivysaur #002 │
84
- charmander #004 │
85
- charmeleon #005 │ Illustration
86
- squirtle #007 │ Types
87
- wartortle #008 │
88
- │ Grass / Poison
89
- │ Characteristics
83
+ ›ivysaur #002 │ Illustration
84
+ charmander #004 │ Types
85
+ charmeleon #005 │
86
+ squirtle #007 │ Grass / Poison
87
+ wartortle #008 │ Characteristics
90
88
 
91
89
  │ - Height: 1m
92
90
  │ - Weight: 13kg
@@ -103,7 +101,9 @@ test('list with detail view display and navigation', async () => {
103
101
 
104
102
  │ Poison
105
103
 
106
- ↵ toggle detail ↑↓ navigate ^k a │ ─────────────────────────────────
104
+ │ ─────────────────────────────────
105
+
106
+ ↵ toggle detail ↑↓ navigate ^k a │ Characteristics ▼
107
107
 
108
108
  "
109
109
  `)
@@ -120,13 +120,11 @@ test('list with detail view display and navigation', async () => {
120
120
  > Search Pokemon...
121
121
 
122
122
  bulbasaur #001 │ charmander ▲
123
- ivysaur #002 │
124
- ›charmander #004 │
125
- charmeleon #005 │ Illustration
126
- squirtle #007 │ Types
127
- wartortle #008 │
128
- │ Fire
129
- │ Characteristics
123
+ ivysaur #002 │ Illustration
124
+ ›charmander #004 │ Types
125
+ charmeleon #005 │
126
+ squirtle #007 │ Fire
127
+ wartortle #008 │ Characteristics
130
128
 
131
129
  │ - Height: 0.6m
132
130
  │ - Weight: 8.5kg
@@ -143,7 +141,9 @@ test('list with detail view display and navigation', async () => {
143
141
 
144
142
  │ Characteristics
145
143
 
146
- ↵ toggle detail ↑↓ navigate ^k a │ Height: 0.6m
144
+ │ Height: 0.6m
145
+
146
+ ↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
147
147
 
148
148
  "
149
149
  `)
@@ -163,8 +163,8 @@ test('list with detail view display and navigation', async () => {
163
163
  > Search Pokemon...
164
164
 
165
165
  bulbasaur #001 │ charmander ▲
166
- ivysaur #002 │
167
- ›charmander #004 │
166
+ ivysaur #002 │ Illustration
167
+ ›charmander #004 │ Types
168
168
  ╭──────────────────────────────────────────────────────────────────────────╮
169
169
  │ │
170
170
  │ Actions esc │
@@ -186,7 +186,7 @@ test('list with detail view display and navigation', async () => {
186
186
  │ │
187
187
  ╰──────────────────────────────────────────────────────────────────────────╯
188
188
 
189
- ↵ toggle detail ↑↓ navigate ^k a │ Height: 0.6m
189
+ ↵ toggle detail ↑↓ navigate ^k a │ ─────────────────────────────────
190
190
 
191
191
  "
192
192
  `)
@@ -304,10 +304,8 @@ test('list detail view search functionality', async () => {
304
304
  > char
305
305
 
306
306
  ›charmander #004 │ charmander ▲
307
- charmeleon #005 │
308
-
309
- │ Illustration
310
- │ Types
307
+ charmeleon #005 │ Illustration
308
+ Types
311
309
 
312
310
  │ Fire
313
311
  │ Characteristics
@@ -327,7 +325,9 @@ test('list detail view search functionality', async () => {
327
325
 
328
326
  │ Characteristics
329
327
 
330
- ↵ toggle detail ↑↓ navigate ^k a │ Height: 0.6m
328
+ │ Height: 0.6m
329
+
330
+ ↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
331
331
 
332
332
  "
333
333
  `)
@@ -353,10 +353,8 @@ test('list detail view search functionality', async () => {
353
353
  > water
354
354
 
355
355
  │ wartortle ▲
356
-
357
- No items found │
358
- │ Illustration
359
- │ Types
356
+ Illustration
357
+ No items found │ Types
360
358
 
361
359
  │ Water
362
360
  │ Characteristics
@@ -376,7 +374,9 @@ test('list detail view search functionality', async () => {
376
374
 
377
375
  │ Characteristics
378
376
 
379
- ↵ toggle detail ↑↓ navigate ^k a │ Height: 1m
377
+ │ Height: 1m
378
+
379
+ ↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
380
380
 
381
381
  "
382
382
  `)
@@ -393,10 +393,8 @@ test('list detail view search functionality', async () => {
393
393
  > water
394
394
 
395
395
  │ wartortle ▲
396
-
397
- No items found │
398
- │ Illustration
399
- │ Types
396
+ Illustration
397
+ No items found │ Types
400
398
 
401
399
  │ Water
402
400
  │ Characteristics
@@ -416,7 +414,9 @@ test('list detail view search functionality', async () => {
416
414
 
417
415
  │ Characteristics
418
416
 
419
- ↵ toggle detail ↑↓ navigate ^k a │ Height: 1m
417
+ │ Height: 1m
418
+
419
+ ↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
420
420
 
421
421
  "
422
422
  `)
@@ -492,13 +492,11 @@ test('list detail metadata rendering', async () => {
492
492
  > Search Pokemon...
493
493
 
494
494
  bulbasaur #001 │ squirtle ▲
495
- ivysaur #002 │
496
- charmander #004 │
497
- charmeleon #005 │ Illustration
498
- ›squirtle #007 │ Types
499
- wartortle #008 │
500
- │ Water
501
- │ Characteristics
495
+ ivysaur #002 │ Illustration
496
+ charmander #004 │ Types
497
+ charmeleon #005 │
498
+ ›squirtle #007 │ Water
499
+ wartortle #008 │ Characteristics
502
500
 
503
501
  │ - Height: 0.5m
504
502
  │ - Weight: 9kg
@@ -515,7 +513,9 @@ test('list detail metadata rendering', async () => {
515
513
 
516
514
  │ Characteristics
517
515
 
518
- ↵ toggle detail ↑↓ navigate ^k a │ Height: 0.5m
516
+ │ Height: 0.5m
517
+
518
+ ↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
519
519
 
520
520
  "
521
521
  `)
@@ -595,9 +595,7 @@ test('list with detail layout consistency - short vs long detail content', async
595
595
 
596
596
  Short Detail │ This item has extensive detail ▲
597
597
  ›Long Detail │ content ▀
598
- Another Item │
599
-
600
- │ Section 1
598
+ Another Item │ Section 1
601
599
 
602
600
  │ This is a very long description
603
601
  │ that contains multiple paragraphs
@@ -609,7 +607,9 @@ test('list with detail layout consistency - short vs long detail content', async
609
607
  │ More content here to ensure we
610
608
  │ have enough text to cause
611
609
  │ vertical overflow in the detail
612
- ↑↓ navigate ^k actions :vim │ panel scrollbox.
610
+ │ panel scrollbox.
611
+ │ Section 3
612
+ ↑↓ navigate ^k actions :vim │ ▼
613
613
 
614
614
  "
615
615
  `)
@@ -49,9 +49,9 @@ test('candle chart renders in list detail with axes', async () => {
49
49
  Mixed Components │ │ │▌▌▘▘ ▘▘
50
50
  BTC - Candles Real BTC/USD hourly candles │ $61,957│ ││
51
51
  ETH - Candle + Line Candles plus closing line │ 12d 8d 4d Now
52
- SOL - Candle + Volume Candles plus volume spli
52
+ SOL - Candle + VolumeCandles plus volume split
53
53
  BTC vs ETH Side-by-side crypto leaders │ Price: $67,641
54
- DOGE - Candle + Line Low-priced asset formatti
54
+ DOGE - Candle + Lin Low-priced ...t formatting
55
55
  │ Change: -0.2%
56
56
 
57
57
  │ Category: Store of Value
@@ -151,9 +151,9 @@ test('candle + line overlay (mixed components)', async () => {
151
151
  Mixed Components │ 12d 8d 4d Now
152
152
  BTC - Candles Real BTC/USD hourly candles │
153
153
  ›ETH - Candle + Line Candles plus closing line │ $2,197│ ⢠⣆⣠⡀
154
- SOL - Candle + Volume Candles plus volume spli │ │ ⣴⣤⣤ ⣀ ⢠⣀ ⢠⣿⣿⣿⣷⣶⣦⡀
154
+ SOL - Candle + VolumeCandles plus volume split │ │ ⣴⣤⣤ ⣀ ⢠⣀ ⢠⣿⣿⣿⣷⣶⣦⡀
155
155
  BTC vs ETH Side-by-side crypto leaders │ $1,997│ ⢰⣿⣿⣿⣿⣿⣇ ⣠⣷⣴⣄⣀⢸⣿⣶⣠⣤⣼⣿⣿⣿⣿⣿⣿⣧⣤⣤⣤
156
- DOGE - Candle + Line Low-priced asset formatti │ │⣶⡄ ⣦⣾⣿⣿⣿⣿⣿⣿⣶⣶⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
156
+ DOGE - Candle + Lin Low-priced ...t formatting │ │⣶⡄ ⣦⣾⣿⣿⣿⣿⣿⣿⣶⣶⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
157
157
  │ $1,797│⣿⣿⣷⣦⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
158
158
  │ 12d 8d 4d Now
159
159
 
@@ -200,9 +200,9 @@ test('candle + volume bar chart (mixed components)', async () => {
200
200
  Mixed Components │ 12d 8d 4d Now
201
201
  BTC - Candles Real BTC/USD hourly candles │
202
202
  ETH - Candle + Line Candles plus closing line │ ┌Second half: 95.3%┐
203
- ›SOL - Candle + Volume Candles plus volume spli
203
+ ›SOL - Candle + VolumeCandles plus volume split
204
204
  BTC vs ETH Side-by-side crypto leaders │
205
- DOGE - Candle + Line Low-priced asset formatti │ ────────────────────────────────────────────
205
+ DOGE - Candle + Lin Low-priced ...t formatting │ ────────────────────────────────────────────
206
206
 
207
207
  │ Price: $83.31
208
208
 
@@ -249,9 +249,9 @@ test('side-by-side candle charts in Row', async () => {
249
249
  Mixed Components │ 30d Now 30d Now
250
250
  BTC - Candles Real BTC/USD hourly candles │
251
251
  ETH - Candle + Line Candles plus closing line │ ────────────────────────────────────────────
252
- SOL - Candle + Volume Candles plus volume spli
252
+ SOL - Candle + VolumeCandles plus volume split
253
253
  ›BTC vs ETH Side-by-side crypto leaders │ Price: $67,641
254
- DOGE - Candle + Line Low-priced asset formatti
254
+ DOGE - Candle + Lin Low-priced ...t formatting
255
255
  │ Change: -0.2%
256
256
 
257
257
 
@@ -0,0 +1,53 @@
1
+ // Example: DottedLineGraph showing metric dashboard lines without box borders.
2
+
3
+ import { Color, DottedLineGraph, Markdown } from 'termcast'
4
+ import { renderWithProviders } from '../utils'
5
+
6
+ const minutes = Array.from({ length: 60 }, (_, index) => {
7
+ if (index < 25) return 18
8
+ if (index < 35) return 74 + (index % 3) * 4
9
+ if (index < 57) return 20
10
+ return 66
11
+ })
12
+
13
+ const memory = Array.from({ length: 60 }, (_, index) => {
14
+ if (index < 24) return 34
15
+ if (index < 40) return 58 + (index % 5) * 3
16
+ return 36
17
+ })
18
+
19
+ const requests2xx = Array.from({ length: 60 }, (_, index) => {
20
+ if (index < 42) return 52
21
+ if (index < 56) return 43
22
+ return 63
23
+ })
24
+
25
+ const requests5xx = Array.from({ length: 60 }, (_, index) => {
26
+ if (index < 12) return 24
27
+ if (index < 45) return 30
28
+ return 28
29
+ })
30
+
31
+ function SimpleDottedLineGraph() {
32
+ return (
33
+ <>
34
+ <Markdown content="## Dotted metrics" />
35
+ <Markdown content="Metric-style dotted lines with braille subcell movement." />
36
+ <DottedLineGraph
37
+ height={12}
38
+ xLabels={['7:28 AM', '7:43 AM', '7:58 AM', '8:13 AM', '8:28 AM']}
39
+ yRange={[0, 100]}
40
+ yTicks={4}
41
+ yFormat={(value) => `${value.toFixed(0)}%`}
42
+ dotSpacing={4}
43
+ >
44
+ <DottedLineGraph.Series data={minutes} color={Color.Blue} title="CPU" />
45
+ <DottedLineGraph.Series data={memory} color={Color.Purple} title="Memory" />
46
+ <DottedLineGraph.Series data={requests2xx} color={Color.Green} title="2xx" />
47
+ <DottedLineGraph.Series data={requests5xx} color={Color.Red} title="5xx" />
48
+ </DottedLineGraph>
49
+ </>
50
+ )
51
+ }
52
+
53
+ void renderWithProviders(<SimpleDottedLineGraph />)
@@ -0,0 +1,62 @@
1
+ import { test, expect, afterEach, beforeEach } from 'vitest'
2
+ import { launchTerminal, Session } from 'tuistory/src'
3
+
4
+ let session: Session
5
+
6
+ beforeEach(async () => {
7
+ session = await launchTerminal({
8
+ command: 'bun',
9
+ args: ['src/examples/simple-dotted-line-graph.tsx'],
10
+ cols: 90,
11
+ rows: 28,
12
+ })
13
+ })
14
+
15
+ afterEach(() => {
16
+ session?.close()
17
+ })
18
+
19
+ test('dotted line graph renders metric lines and legend', async () => {
20
+ const text = await session.text({
21
+ waitFor: (text) => {
22
+ return text.includes('Dotted metrics') && text.includes('CPU') && text.includes('│')
23
+ },
24
+ timeout: 10000,
25
+ })
26
+
27
+ expect(text).toMatchInlineSnapshot(`
28
+ "
29
+
30
+
31
+ Dotted metrics
32
+ Metric-style dotted lines with braille subcell movement.
33
+ 100%│
34
+
35
+ │ ⠄⠈⢀ ⠄⠈⢀ ⠠⠈⢀ ⠠
36
+ │ ⠠ ⠁ ⠁ ⠠ ⠁ ⠁⠰ ⠄
37
+ 67%│ ⠈⠊ ⠠ ⠂⠁ ⠂ ⠠⠐ ⠁ ⠂ ⠄⠐ ⠁⠐ ⠐ ⡃⠃⠘
38
+ │⡀⢀⢀ ⡀⢀ ⡀⡀⢀ ⡀⢀⢀ ⡀⢀⢀ ⡀⢀ ⡀⡀⢀ ⡀⢀⢀ ⡀⢀⢁⠈⡁⢀ ⡀⡀⢀ ⡁⢀⢀ ⡀⢀⠂⡁⡀⢀ ⡀⡐⢀ ⡀ ⠁⢀
39
+ │ ⠁⠈ ⠐ ⠂ ⢄⢀ ⡀⢀ ⡀⡀⢀ ⡀⡀⢀ ⡀⢀⢀ ⡈ ⡀
40
+ 33%│⡀⢀⢀ ⡀⢀ ⡀⡀⢀ ⡀⢀⢀ ⡀⢀⢀ ⡀⢀ ⡀⡀⢀ ⡀⢀⢀ ⡀⢈ ⠁ ⠐ ⠰ ⠄⠠⠠ ⠄⠠ ⠄⠄⠠ ⠄⠄⠠ ⠄⠠⠠ ⠄⠠⡀⠄⠄⠠
41
+ │ ⠐⠐ ⠂⠐ ⠂⠂⠐ ⠂⠐⠐ ⠂⠐⠐⠁⠂⠐ ⠂⠂⠐ ⠂⠐⠐ ⠂⠐⠐⠂⠂⠐ ⠂⠂⠐ ⠂⠐⠐ ⠂⠠ ⠄⠄⠠ ⠄⠄⠠ ⠄⠠⠠ ⠄⢠ ⠄⠄⠠
42
+ │⡁⢈⢈ ⡁⢈ ⡁⡁⢈ ⡁⢈⢈ ⡁⢀⢀ ⡀⢀ ⡀⡀⢀ ⡀⢀⢀ ⡀⢀⢈ ⠆⠄⠠ ⠄⠄⠠ ⠄⠠⠠ ⠄⠠ ⠄⠄⠠ ⠄⠄⠠ ⠄⠠⠠ ⠄⠠
43
+
44
+ 0%│
45
+ 7:28 AM 7:43 AM 7:58 AM 8:13 AM 8:28 AM
46
+ ● CPU ● Memory ● 2xx ● 5xx
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+ "
57
+ `)
58
+ expect(text).toContain('Dotted metrics')
59
+ expect(text).toContain('CPU')
60
+ expect(text).toContain('8:28 AM')
61
+ expect(text).toMatch(/[\u2800-\u28FF]/)
62
+ }, 30000)
@@ -228,7 +228,7 @@ test('grid search functionality', async () => {
228
228
  🚀 Rocket
229
229
  ⭐ Star
230
230
  🌙 Moon
231
- Sun
231
+ ☀️ Sun
232
232
 
233
233
 
234
234
  ↵ show details ↑↓ navigate ^k actions :vim
@@ -268,7 +268,7 @@ test('grid search functionality', async () => {
268
268
  🚀 Rocket
269
269
  ⭐ Star
270
270
  🌙 Moon
271
- Sun
271
+ ☀️ Sun
272
272
 
273
273
 
274
274
  ↵ show details ↑↓ navigate ^k actions :vim
@@ -342,7 +342,7 @@ test('grid search functionality', async () => {
342
342
  🚀 Rocket
343
343
  ⭐ Star
344
344
  🌙 Moon
345
- Sun
345
+ ☀️ Sun
346
346
 
347
347
 
348
348
  ↵ show details ↑↓ navigate ^k actions :vim
@@ -535,7 +535,7 @@ test('grid mouse interaction', async () => {
535
535
  🚀 Rocket
536
536
  ›⭐ Star
537
537
  🌙 Moon
538
- Sun
538
+ ☀️ Sun
539
539
 
540
540
 
541
541
 
@@ -36,12 +36,12 @@ test('renders calendar heatmaps with various color combinations', async () => {
36
36
  Calendar Heatmap Color Showcase
37
37
 
38
38
 
39
+ Each heatmap demonstrates a different color combination.
40
+ Data has a late-fall gap to show that empty weeks are skipped.
41
+ Last heatmap renders multi-year data to verify width truncation.
39
42
 
40
-
41
-
42
-
43
-
44
-
43
+ Long history — 5 years of daily data in purple. Months that don't fit the
44
+ terminal width are truncated from the left.
45
45
 
46
46
  May Jun Jul Aug Sep Oct Nov
47
47
  ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
@@ -53,8 +53,8 @@ test('renders calendar heatmaps with various color combinations', async () => {
53
53
  ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
54
54
  Less ◼ ◼ ■ ■ More
55
55
 
56
-
57
-
56
+ Journal — summer + winter entries in green, with a fall gap between the two
57
+ ranges.
58
58
 
59
59
  Jun Jul Aug Sep Jan Feb
60
60
  ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
@@ -66,14 +66,14 @@ test('renders calendar heatmaps with various color combinations', async () => {
66
66
  ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
67
67
  Less ◼ ◼ ■ ■ More
68
68
 
69
-
70
-
69
+ Recent activity — last 150 days in red, showing the sine-wave pattern clearly.
71
70
 
72
71
  Se Oct Nov Dec Jan Feb
73
72
  ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
74
73
  ■ ◼ ◼ ◼ ■ ■ ■ ◼ ◼ ◼ ■ ■ ◼ ◼ ◼ ■ ■ ■ ◼ ◼ ■ Mon
75
74
  ■ ◼ ◼ ◼ ■ ■ ■ ◼ ◼ ■ ■ ■ ◼ ◼ ◼ ■ ■ ◼ ◼ ◼ ■
76
75
  ■ ■ ◼ ◼ ◼ ■ ■ ■ ◼ ◼ ■ ■ ■ ◼ ◼ ◼ ■ ■ ◼ ◼ ◼ ■ Wed
76
+ ■ ■ ◼ ◼ ◼ ■ ■ ◼ ◼ ◼ ■ ■ ■ ◼ ◼ ◼ ■ ■ ◼ ◼ ◼ ■
77
77
 
78
78
 
79
79
  esc go back ^k actions powered by termcast.app
@@ -0,0 +1,90 @@
1
+ // Example: Histogram component showing action distribution from an AI coding session.
2
+ // Replicates the horizontal distribution table with colored dots, counts, percentages,
3
+ // and bar visualization.
4
+
5
+ import React from 'react'
6
+ import { List, Histogram, Color } from 'termcast'
7
+ import { renderWithProviders } from '../utils'
8
+
9
+ // ── Data ─────────────────────────────────────────────────────────────
10
+
11
+ interface SessionData {
12
+ title: string
13
+ subtitle: string
14
+ actions: Array<{ label: string; value: number; color?: Color.ColorLike }>
15
+ }
16
+
17
+ const sessions: SessionData[] = [
18
+ {
19
+ title: 'Session: refactor(dataset)',
20
+ subtitle: '257 steps · 47m 12s wall · 5.4M tokens',
21
+ actions: [
22
+ { label: 'user', value: 5, color: Color.Orange },
23
+ { label: 'think', value: 13, color: Color.SecondaryText },
24
+ { label: 'read', value: 44, color: '#00CCCC' },
25
+ { label: 'edit', value: 108, color: Color.Purple },
26
+ { label: 'bash', value: 64, color: Color.Yellow },
27
+ { label: 'write', value: 17, color: Color.Green },
28
+ { label: 'grep/glob', value: 6, color: Color.Blue },
29
+ ],
30
+ },
31
+ {
32
+ title: 'Session: add dark mode',
33
+ subtitle: '89 steps · 12m 30s wall · 1.2M tokens',
34
+ actions: [
35
+ { label: 'user', value: 8 },
36
+ { label: 'think', value: 20 },
37
+ { label: 'read', value: 15 },
38
+ { label: 'edit', value: 30 },
39
+ { label: 'bash', value: 12 },
40
+ { label: 'write', value: 4 },
41
+ ],
42
+ },
43
+ {
44
+ title: 'Session: fix auth bug',
45
+ subtitle: '42 steps · 5m 18s wall · 800K tokens',
46
+ actions: [
47
+ { label: 'think', value: 10 },
48
+ { label: 'read', value: 8 },
49
+ { label: 'edit', value: 15 },
50
+ { label: 'bash', value: 7 },
51
+ { label: 'grep/glob', value: 2 },
52
+ ],
53
+ },
54
+ ]
55
+
56
+ // ── Component ────────────────────────────────────────────────────────
57
+
58
+ function HistogramExample() {
59
+ return (
60
+ <List navigationTitle="Histogram Showcase" isShowingDetail={true}>
61
+ {sessions.map((session) => (
62
+ <List.Item
63
+ key={session.title}
64
+ title={session.title}
65
+ subtitle={session.subtitle}
66
+ detail={
67
+ <List.Item.Detail
68
+ metadata={
69
+ <List.Item.Detail.Metadata>
70
+ <Histogram maxBarWidth={30}>
71
+ {session.actions.map((action) => (
72
+ <Histogram.Item
73
+ key={action.label}
74
+ label={action.label}
75
+ value={action.value}
76
+ color={action.color}
77
+ />
78
+ ))}
79
+ </Histogram>
80
+ </List.Item.Detail.Metadata>
81
+ }
82
+ />
83
+ }
84
+ />
85
+ ))}
86
+ </List>
87
+ )
88
+ }
89
+
90
+ renderWithProviders(<HistogramExample />)
@@ -111,7 +111,7 @@ test('navigation between main and detail views', async () => {
111
111
  > Detail view - Press ESC to go back
112
112
 
113
113
  Details
114
- ›This is the detail view for Second Item Press Enter to go back o
114
+ ›This is the d...r Second ItemPress Enter to g...to navigate back
115
115
 
116
116
 
117
117
 
@@ -220,7 +220,7 @@ test('navigation between main and detail views', async () => {
220
220
  > Detail view - Press ESC to go back
221
221
 
222
222
  Details
223
- ›This is the detail view for Third Item Press Enter to go back or
223
+ ›This is the d...or Third Ite Press Enter to g...to navigate back
224
224
 
225
225
 
226
226
 
@@ -412,7 +412,7 @@ test('navigation with actions panel', async () => {
412
412
  > Detail view - Press ESC to go back
413
413
 
414
414
  Details
415
- ›This is the detail view for Second Item Press Enter to go back o
415
+ ›This is the d...r Second ItemPress Enter to g...to navigate back
416
416
 
417
417
 
418
418
 
@@ -606,7 +606,7 @@ test('search functionality in main and detail views', async () => {
606
606
  > Detail view - Press ESC to go back
607
607
 
608
608
  Details
609
- ›This is the detail view for First Item Press Enter to go back or
609
+ ›This is the d...or First Ite Press Enter to g...to navigate back
610
610
 
611
611
 
612
612
 
@@ -82,7 +82,7 @@ afterEach(() => {
82
82
  test.skipIf(isLinux)('swift extension dev mode shows command list', async () => {
83
83
  // Wait for command list to appear
84
84
  const commandList = await session.text({
85
- waitFor: (text) => /Swift List/i.test(text),
85
+ waitFor: (text) => /Swift Lis/i.test(text),
86
86
  timeout: 30000,
87
87
  })
88
88
 
@@ -96,7 +96,7 @@ test.skipIf(isLinux)('swift extension dev mode shows command list', async () =>
96
96
 
97
97
  Commands
98
98
  ›List Items Displays a simple list with some items view
99
- Swift List Displays a list of items returned by a Swift fun view
99
+ Swift Lis Displays a list of item...ned by a Swift function view
100
100
 
101
101
 
102
102
 
@@ -119,7 +119,7 @@ test.skipIf(isLinux)('swift extension dev mode shows command list', async () =>
119
119
  test.skipIf(isLinux)('swift extension runs Swift List command and shows items', async () => {
120
120
  // Wait for command list to appear
121
121
  await session.text({
122
- waitFor: (text) => /Swift List/i.test(text),
122
+ waitFor: (text) => /Swift Lis/i.test(text),
123
123
  timeout: 30000,
124
124
  })
125
125
 
@@ -59,10 +59,10 @@ test('dev command shows extension commands list', async () => {
59
59
 
60
60
  Commands
61
61
  ›List Items Displays a simple list with some items view
62
- Search Items Search and filter through a list of view
62
+ Sear...temsSearch and filter...gh a list of items view
63
63
  Google Oauth view
64
- usePromise Demo Shows how to use the usePromise h view
65
- Show State Shows the current application state in view
64
+ useP...DemoShows how to use ...rom @raycast/utils view
65
+ Sh...ateShows the current a...tate in JSON format view
66
66
 
67
67
 
68
68
  ↵ run command ↑↓ navigate ^k actions :vim
@@ -93,11 +93,11 @@ test('selecting command with arguments shows arguments form', async () => {
93
93
 
94
94
  > Search commands...
95
95
 
96
- usePromise Demo Shows how to use the usePromise h view
97
- Show State Shows the current application state in view
98
- ›With Arguments Demonstrates command arguments (te view
99
- Quick Action Copies current timestamp to clipb no-view
100
- Throw Error Command that throws an error at root view
96
+ useP...DemoShows how to use ...rom @raycast/utils view
97
+ Sh...ateShows the current a...tate in JSON format view
98
+ ›With...ent Demonstrates comm...assword, dropdown) view
99
+ Qui...ionCopies current ti...ut showing a view no-view
100
+ Thr...rrorCommand that throw...rror at root scope view
101
101
 
102
102
 
103
103