termcast 1.3.33 → 1.3.35

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 (88) hide show
  1. package/dist/apis/cache.d.ts +1 -2
  2. package/dist/apis/cache.d.ts.map +1 -1
  3. package/dist/apis/cache.js +134 -52
  4. package/dist/apis/cache.js.map +1 -1
  5. package/dist/build.d.ts.map +1 -1
  6. package/dist/build.js +25 -0
  7. package/dist/build.js.map +1 -1
  8. package/dist/cli.js +6 -8
  9. package/dist/cli.js.map +1 -1
  10. package/dist/components/dropdown.js +3 -3
  11. package/dist/components/dropdown.js.map +1 -1
  12. package/dist/components/footer.d.ts.map +1 -1
  13. package/dist/components/footer.js +1 -1
  14. package/dist/components/footer.js.map +1 -1
  15. package/dist/components/icon.d.ts.map +1 -1
  16. package/dist/components/icon.js +386 -23
  17. package/dist/components/icon.js.map +1 -1
  18. package/dist/components/list.d.ts.map +1 -1
  19. package/dist/components/list.js +90 -22
  20. package/dist/components/list.js.map +1 -1
  21. package/dist/examples/list-controlled-search.d.ts +2 -0
  22. package/dist/examples/list-controlled-search.d.ts.map +1 -0
  23. package/dist/examples/list-controlled-search.js +12 -0
  24. package/dist/examples/list-controlled-search.js.map +1 -0
  25. package/dist/extensions/home.js +1 -1
  26. package/dist/extensions/home.js.map +1 -1
  27. package/dist/extensions/react-refresh-init.d.ts.map +1 -1
  28. package/dist/extensions/react-refresh-init.js +4 -3
  29. package/dist/extensions/react-refresh-init.js.map +1 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/internal/dialog.d.ts.map +1 -1
  34. package/dist/internal/dialog.js +4 -5
  35. package/dist/internal/dialog.js.map +1 -1
  36. package/dist/internal/providers.d.ts.map +1 -1
  37. package/dist/internal/providers.js +18 -5
  38. package/dist/internal/providers.js.map +1 -1
  39. package/dist/state.d.ts +1 -0
  40. package/dist/state.d.ts.map +1 -1
  41. package/dist/state.js.map +1 -1
  42. package/dist/theme.d.ts.map +1 -1
  43. package/dist/theme.js +6 -2
  44. package/dist/theme.js.map +1 -1
  45. package/dist/utils/run-command.js +3 -3
  46. package/dist/utils/run-command.js.map +1 -1
  47. package/dist/utils.d.ts +16 -1
  48. package/dist/utils.d.ts.map +1 -1
  49. package/dist/utils.js +28 -1
  50. package/dist/utils.js.map +1 -1
  51. package/dist/watcher.d.ts.map +1 -1
  52. package/dist/watcher.js +24 -4
  53. package/dist/watcher.js.map +1 -1
  54. package/package.json +10 -9
  55. package/src/apis/cache.test.ts +35 -3
  56. package/src/apis/cache.tsx +180 -57
  57. package/src/build.tsx +28 -0
  58. package/src/cli.tsx +8 -10
  59. package/src/compile.vitest.tsx +42 -24
  60. package/src/components/dropdown.tsx +3 -3
  61. package/src/components/footer.tsx +4 -2
  62. package/src/components/icon.tsx +385 -23
  63. package/src/components/list.tsx +104 -28
  64. package/src/examples/github.vitest.tsx +37 -37
  65. package/src/examples/list-controlled-search.tsx +28 -0
  66. package/src/examples/list-controlled-search.vitest.tsx +49 -0
  67. package/src/examples/list-detail-metadata.vitest.tsx +1 -1
  68. package/src/examples/list-dropdown-default.vitest.tsx +9 -9
  69. package/src/examples/list-scrollbox.vitest.tsx +55 -41
  70. package/src/examples/list-with-detail.vitest.tsx +35 -36
  71. package/src/examples/list-with-dropdown.vitest.tsx +2 -2
  72. package/src/examples/list-with-sections.vitest.tsx +153 -118
  73. package/src/examples/simple-file-picker.vitest.tsx +1 -1
  74. package/src/examples/simple-grid.vitest.tsx +44 -44
  75. package/src/examples/simple-navigation.vitest.tsx +43 -12
  76. package/src/examples/store.vitest.tsx +1 -1
  77. package/src/examples/swift-extension.vitest.tsx +3 -3
  78. package/src/extensions/dev.vitest.tsx +69 -34
  79. package/src/extensions/home.tsx +1 -1
  80. package/src/extensions/react-refresh-init.tsx +4 -3
  81. package/src/index.tsx +1 -0
  82. package/src/internal/dialog.tsx +21 -23
  83. package/src/internal/providers.tsx +18 -5
  84. package/src/state.tsx +1 -0
  85. package/src/theme.tsx +6 -2
  86. package/src/utils/run-command.tsx +3 -3
  87. package/src/utils.tsx +41 -1
  88. package/src/watcher.tsx +26 -6
@@ -38,9 +38,9 @@ test('grid navigation and display', async () => {
38
38
 
39
39
  > Search items...
40
40
 
41
- Fruits
42
- ›🍎 Apple
43
- 🍌 Banana
41
+ Fruits
42
+ ›🍎 Apple
43
+ 🍌 Banana
44
44
  🍒 Cherry
45
45
 
46
46
  Animals
@@ -51,7 +51,7 @@ test('grid navigation and display', async () => {
51
51
  Others
52
52
  🏠 House
53
53
  🚗 Car
54
- 🚀 Rocket
54
+ 🚀 Rocket
55
55
 
56
56
 
57
57
  ↵ show details ↑↓ navigate ^k actions
@@ -71,9 +71,9 @@ test('grid navigation and display', async () => {
71
71
 
72
72
  > Search items...
73
73
 
74
- Fruits
75
- 🍎 Apple
76
- ›🍌 Banana
74
+ Fruits
75
+ ›🍎 Apple
76
+ 🍌 Banana
77
77
  🍒 Cherry
78
78
 
79
79
  Animals
@@ -84,7 +84,7 @@ test('grid navigation and display', async () => {
84
84
  Others
85
85
  🏠 House
86
86
  🚗 Car
87
- 🚀 Rocket
87
+ 🚀 Rocket
88
88
 
89
89
 
90
90
  ↵ show details ↑↓ navigate ^k actions
@@ -105,9 +105,9 @@ test('grid navigation and display', async () => {
105
105
 
106
106
  > Search items...
107
107
 
108
- Fruits
109
- 🍎 Apple
110
- 🍌 Banana
108
+ Fruits
109
+ 🍎 Apple
110
+ 🍌 Banana
111
111
  🍒 Cherry
112
112
 
113
113
  Animals
@@ -118,7 +118,7 @@ test('grid navigation and display', async () => {
118
118
  Others
119
119
  🏠 House
120
120
  🚗 Car
121
- 🚀 Rocket
121
+ 🚀 Rocket
122
122
 
123
123
 
124
124
  ↵ show details ↑↓ navigate ^k actions
@@ -134,9 +134,9 @@ test('grid navigation and display', async () => {
134
134
  "
135
135
 
136
136
 
137
+ Simple Grid Example ────────────────────────────────────────────
137
138
 
138
-
139
-
139
+ > Search items...
140
140
 
141
141
  ╭────────────────────────────────────────────────────────────────╮
142
142
  │ │
@@ -171,9 +171,9 @@ test('grid navigation and display', async () => {
171
171
 
172
172
  > Search items...
173
173
 
174
- Fruits
175
- 🍎 Apple
176
- 🍌 Banana
174
+ Fruits
175
+ 🍎 Apple
176
+ 🍌 Banana
177
177
  🍒 Cherry
178
178
 
179
179
  Animals
@@ -184,7 +184,7 @@ test('grid navigation and display', async () => {
184
184
  Others
185
185
  🏠 House
186
186
  🚗 Car
187
- 🚀 Rocket
187
+ 🚀 Rocket
188
188
 
189
189
 
190
190
  ↵ show details ↑↓ navigate ^k actions
@@ -294,9 +294,9 @@ test('grid search functionality', async () => {
294
294
 
295
295
  > Search items...
296
296
 
297
- Fruits
298
- ›🍎 Apple
299
- 🍌 Banana
297
+ Fruits
298
+ ›🍎 Apple
299
+ 🍌 Banana
300
300
  🍒 Cherry
301
301
 
302
302
  Animals
@@ -307,7 +307,7 @@ test('grid search functionality', async () => {
307
307
  Others
308
308
  🏠 House
309
309
  🚗 Car
310
- 🚀 Rocket
310
+ 🚀 Rocket
311
311
 
312
312
 
313
313
  ↵ show details ↑↓ navigate ^k actions
@@ -373,9 +373,9 @@ test('grid item selection and actions', async () => {
373
373
 
374
374
  > Search items...
375
375
 
376
- Fruits
377
- ›🍎 Apple
378
- 🍌 Banana
376
+ Fruits
377
+ ›🍎 Apple
378
+ 🍌 Banana
379
379
  🍒 Cherry
380
380
 
381
381
  Animals
@@ -386,7 +386,7 @@ test('grid item selection and actions', async () => {
386
386
  Others
387
387
  🏠 House
388
388
  🚗 Car
389
- 🚀 Rocket
389
+ 🚀 Rocket
390
390
 
391
391
 
392
392
  ↵ show details ↑↓ navigate ^k actions
@@ -406,9 +406,9 @@ test('grid item selection and actions', async () => {
406
406
 
407
407
  > Search items...
408
408
 
409
- Fruits
410
- 🍎 Apple
411
- ›🍌 Banana
409
+ Fruits
410
+ 🍎 Apple
411
+ ›🍌 Banana
412
412
  🍒 Cherry
413
413
 
414
414
  Animals
@@ -419,7 +419,7 @@ test('grid item selection and actions', async () => {
419
419
  Others
420
420
  🏠 House
421
421
  🚗 Car
422
- 🚀 Rocket
422
+ 🚀 Rocket
423
423
 
424
424
 
425
425
  ↵ show details ↑↓ navigate ^k actions
@@ -439,9 +439,9 @@ test('grid item selection and actions', async () => {
439
439
 
440
440
  > Search items...
441
441
 
442
- Fruits
443
- 🍎 Apple
444
- ›🍌 Banana
442
+ Fruits
443
+ 🍎 Apple
444
+ ›🍌 Banana
445
445
  🍒 Cherry
446
446
 
447
447
  Animals
@@ -452,7 +452,7 @@ test('grid item selection and actions', async () => {
452
452
  Others
453
453
  🏠 House
454
454
  🚗 Car
455
- 🚀 Rocket
455
+ 🚀 Rocket
456
456
 
457
457
 
458
458
  ↵ show details ↑↓ navigate ^k actions
@@ -481,9 +481,9 @@ test('grid mouse interaction', async () => {
481
481
 
482
482
  > Search items...
483
483
 
484
- Fruits
485
- 🍎 Apple
486
- 🍌 Banana
484
+ Fruits
485
+ 🍎 Apple
486
+ 🍌 Banana
487
487
  🍒 Cherry
488
488
 
489
489
  Animals
@@ -494,7 +494,7 @@ test('grid mouse interaction', async () => {
494
494
  Others
495
495
  🏠 House
496
496
  🚗 Car
497
- 🚀 Rocket
497
+ 🚀 Rocket
498
498
 
499
499
 
500
500
  ↵ show details ↑↓ navigate ^k actions
@@ -519,9 +519,9 @@ test('grid mouse interaction', async () => {
519
519
  "
520
520
 
521
521
 
522
+ Simple Grid Example ────────────────────────────────────────────
522
523
 
523
-
524
-
524
+ > Search items...
525
525
 
526
526
  ╭────────────────────────────────────────────────────────────────╮
527
527
  │ │
@@ -567,9 +567,9 @@ test('grid mouse interaction', async () => {
567
567
 
568
568
  > Search items...
569
569
 
570
- Fruits
571
- ›🍎 Apple
572
- 🍌 Banana
570
+ Fruits
571
+ ›🍎 Apple
572
+ 🍌 Banana
573
573
  🍒 Cherry
574
574
 
575
575
  Animals
@@ -580,7 +580,7 @@ test('grid mouse interaction', async () => {
580
580
  Others
581
581
  🏠 House
582
582
  🚗 Car
583
- 🚀 Rocket
583
+ 🚀 Rocket
584
584
 
585
585
 
586
586
  ↵ show details ↑↓ navigate ^k actions
@@ -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
114
+ ›This is the detail view for Second Item Press Enter to go back o
115
115
 
116
116
 
117
117
 
@@ -153,8 +153,8 @@ test('navigation between main and detail views', async () => {
153
153
  > Main view
154
154
 
155
155
  Items
156
- First Item Navigate to first detail
157
- Second Item Navigate to second detail
156
+ First Item Navigate to first detail
157
+ Second Item Navigate to second detail
158
158
  Third Item Navigate to third detail
159
159
 
160
160
 
@@ -187,9 +187,9 @@ test('navigation between main and detail views', async () => {
187
187
  > Main view
188
188
 
189
189
  Items
190
- First Item Navigate to first detail
190
+ First Item Navigate to first detail
191
191
  Second Item Navigate to second detail
192
- Third Item Navigate to third detail
192
+ Third Item Navigate to third detail
193
193
 
194
194
 
195
195
 
@@ -215,12 +215,12 @@ test('navigation between main and detail views', async () => {
215
215
  "
216
216
 
217
217
 
218
- Detail: Third Item ─────────────────────────────────────────────
218
+ Detail: First Item ─────────────────────────────────────────────
219
219
 
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 o
223
+ ›This is the detail view for First Item Press Enter to go back or
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
415
+ ›This is the detail view for Second Item Press Enter to go back o
416
416
 
417
417
 
418
418
 
@@ -482,8 +482,8 @@ test('navigation with actions panel', async () => {
482
482
  > Main view
483
483
 
484
484
  Items
485
- First Item Navigate to first detail
486
- Second Item Navigate to second detail
485
+ First Item Navigate to first detail
486
+ Second Item Navigate to second detail
487
487
  Third Item Navigate to third detail
488
488
 
489
489
 
@@ -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 o
609
+ ›This is the detail view for First Item Press Enter to go back or
610
610
 
611
611
 
612
612
 
@@ -644,7 +644,7 @@ test('search functionality in main and detail views', async () => {
644
644
 
645
645
 
646
646
 
647
- No items found
647
+ No items found
648
648
 
649
649
 
650
650
 
@@ -700,3 +700,34 @@ test('search functionality in main and detail views', async () => {
700
700
  "
701
701
  `)
702
702
  }, 10000)
703
+
704
+ test('keeps selected item after opening detail and pressing esc', async () => {
705
+ await session.text({
706
+ waitFor: (text) => {
707
+ return /Navigation Example/i.test(text) && /First Item/i.test(text)
708
+ },
709
+ })
710
+
711
+ await session.press('down')
712
+ const selectedSecondSnapshot = await session.text()
713
+ expect(selectedSecondSnapshot).toContain('›Second Item')
714
+
715
+ await session.press('enter')
716
+ await session.text({
717
+ waitFor: (text) => {
718
+ return /Detail: Second Item/i.test(text)
719
+ },
720
+ timeout: 3000,
721
+ })
722
+
723
+ await session.press('esc')
724
+ const backSnapshot = await session.text({
725
+ waitFor: (text) => {
726
+ return /Navigation Example/i.test(text)
727
+ },
728
+ timeout: 3000,
729
+ })
730
+
731
+ expect(backSnapshot).toContain('›Second Item')
732
+ expect(backSnapshot).not.toContain('›First Item')
733
+ }, 10000)
@@ -50,7 +50,7 @@ test('Store extension - searching for spiceblow shows Database', async () => {
50
50
 
51
51
  > spiceblow
52
52
 
53
- ›Spiceblow - Sql Database Management Search, update, insert and delete row
53
+ ›Spiceblow - Sql Database Management Search, update, insert and delete rows
54
54
 
55
55
 
56
56
 
@@ -89,13 +89,14 @@ test.skipIf(isLinux)('swift extension dev mode shows command list', async () =>
89
89
  > Search commands...
90
90
 
91
91
  Commands
92
- ›List Items Displays a simple list with some items view
93
- Swift List Displays a list of items returned by a Swift f view
92
+ ›List Items Displays a simple list with some items view
93
+ Swift List Displays a list of items returned by a Swift fun view
94
94
 
95
95
 
96
96
 
97
97
 
98
98
 
99
+ ↵ run command ↑↓ navigate ^k actions
99
100
 
100
101
 
101
102
 
@@ -104,7 +105,6 @@ test.skipIf(isLinux)('swift extension dev mode shows command list', async () =>
104
105
 
105
106
 
106
107
 
107
- ↵ run command ↑↓ navigate ^k actions
108
108
 
109
109
  "
110
110
  `)
@@ -1,11 +1,33 @@
1
1
  import { test, expect, afterEach, beforeEach } from 'vitest'
2
2
  import { launchTerminal, Session } from 'tuistory/src'
3
+ import fs from 'node:fs'
3
4
  import path from 'node:path'
4
5
 
5
6
  let session: Session
6
7
 
7
8
  const fixtureDir = path.resolve(__dirname, '../../fixtures/simple-extension')
8
9
 
10
+ async function waitForTextWithDebug({
11
+ session,
12
+ waitFor,
13
+ timeout,
14
+ }: {
15
+ session: Session
16
+ waitFor: (text: string) => boolean
17
+ timeout: number
18
+ }): Promise<string> {
19
+ try {
20
+ return await session.text({ waitFor, timeout })
21
+ } catch (error) {
22
+ const logPath = path.resolve(process.cwd(), 'app.log')
23
+ const appLog = fs.existsSync(logPath)
24
+ ? fs.readFileSync(logPath, 'utf-8').slice(-8000)
25
+ : 'app.log not found'
26
+ const message = error instanceof Error ? error.message : String(error)
27
+ throw new Error(`${message}\n\napp.log tail:\n${appLog}`)
28
+ }
29
+ }
30
+
9
31
  beforeEach(async () => {
10
32
  session = await launchTerminal({
11
33
  command: 'bun',
@@ -20,7 +42,8 @@ afterEach(() => {
20
42
  })
21
43
 
22
44
  test('dev command shows extension commands list', async () => {
23
- await session.text({
45
+ await waitForTextWithDebug({
46
+ session,
24
47
  waitFor: (text) => /Simple Test Extension/i.test(text),
25
48
  timeout: 10000,
26
49
  })
@@ -34,12 +57,12 @@ test('dev command shows extension commands list', async () => {
34
57
 
35
58
  > Search commands...
36
59
 
37
- Commands
38
- ›List Items Displays a simple list with some ite view
39
- Search Items Search and filter through a list o view
40
- Google Oauth view
41
- usePromise Demo Shows how to use the usePromise view
42
- Show State Shows the current application state view
60
+ Commands
61
+ ›List Items Displays a simple list with some items view
62
+ Search Items Search and filter through a list of view
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
43
66
 
44
67
 
45
68
  ↵ run command ↑↓ navigate ^k actions
@@ -48,7 +71,8 @@ test('dev command shows extension commands list', async () => {
48
71
  }, 30000)
49
72
 
50
73
  test('selecting command with arguments shows arguments form', async () => {
51
- await session.text({
74
+ await waitForTextWithDebug({
75
+ session,
52
76
  waitFor: (text) => /Simple Test Extension/i.test(text),
53
77
  timeout: 10000,
54
78
  })
@@ -69,12 +93,12 @@ test('selecting command with arguments shows arguments form', async () => {
69
93
 
70
94
  > Search commands...
71
95
 
72
- Google Oauth view
73
- usePromise Demo Shows how to use the usePromise view
74
- Show State Shows the current application state view
75
- ›With Arguments Demonstrates command arguments ( view
76
- Quick Action Copies current timestamp to cli no-view
77
- Throw Error Command that throws an error at roo view
96
+ Google Oauth view
97
+ usePromise Demo Shows how to use the usePromise h view
98
+ Show State Shows the current application state in view
99
+ ›With Arguments Demonstrates command arguments (te view
100
+ Quick Action Copies current timestamp to clipb no-view
101
+ Throw Error Command that throws an error at root view
78
102
 
79
103
 
80
104
  ↵ run command ↑↓ navigate ^k actions
@@ -85,7 +109,8 @@ test('selecting command with arguments shows arguments form', async () => {
85
109
  await session.press('enter')
86
110
  await session.press('enter')
87
111
 
88
- await session.text({
112
+ await waitForTextWithDebug({
113
+ session,
89
114
  waitFor: (text) => /Search query/i.test(text),
90
115
  timeout: 10000,
91
116
  })
@@ -113,7 +138,8 @@ test('selecting command with arguments shows arguments form', async () => {
113
138
  }, 30000)
114
139
 
115
140
  test('can fill arguments and run command', async () => {
116
- await session.text({
141
+ await waitForTextWithDebug({
142
+ session,
117
143
  waitFor: (text) => /Simple Test Extension/i.test(text),
118
144
  timeout: 10000,
119
145
  })
@@ -127,7 +153,8 @@ test('can fill arguments and run command', async () => {
127
153
  await session.press('enter')
128
154
  await session.press('enter')
129
155
 
130
- await session.text({
156
+ await waitForTextWithDebug({
157
+ session,
131
158
  waitFor: (text) => /Search query/i.test(text),
132
159
  timeout: 10000,
133
160
  })
@@ -161,7 +188,8 @@ test('can fill arguments and run command', async () => {
161
188
  await session.waitIdle()
162
189
  await session.press('enter')
163
190
 
164
- await session.text({
191
+ await waitForTextWithDebug({
192
+ session,
165
193
  waitFor: (text) => /Received Arguments/i.test(text),
166
194
  timeout: 10000,
167
195
  })
@@ -176,9 +204,9 @@ test('can fill arguments and run command', async () => {
176
204
  > Search...
177
205
 
178
206
  Received Arguments
179
- ›▼ Search Query (empty)
180
- Secret Key (empty)
181
- Category (empty)
207
+ ›𝐓 Search Query (empty)
208
+ 𝐓 Secret Key (empty)
209
+ 𝐓 Category (empty)
182
210
 
183
211
 
184
212
 
@@ -189,7 +217,8 @@ test('can fill arguments and run command', async () => {
189
217
  }, 30000)
190
218
 
191
219
  test('can run simple view command without arguments', async () => {
192
- await session.text({
220
+ await waitForTextWithDebug({
221
+ session,
193
222
  waitFor: (text) => /Simple Test Extension/i.test(text),
194
223
  timeout: 10000,
195
224
  })
@@ -198,7 +227,8 @@ test('can run simple view command without arguments', async () => {
198
227
  await session.press('enter')
199
228
  await session.press('enter')
200
229
 
201
- await session.text({
230
+ await waitForTextWithDebug({
231
+ session,
202
232
  waitFor: (text) => /First Item/i.test(text),
203
233
  timeout: 10000,
204
234
  })
@@ -212,12 +242,12 @@ test('can run simple view command without arguments', async () => {
212
242
 
213
243
  > Search...
214
244
 
215
- Items
216
- ›▲ First Item This is the first item
217
- Second Item This is the second item
218
- Third Item This is the third item
219
- Fourth Item This is the fourth item
220
- Fifth Item This is the fifth item
245
+ Items
246
+ ›○ First Item This is the first item
247
+ Second Item This is the second item
248
+ Third Item This is the third item
249
+ Fourth Item This is the fourth item
250
+ Fifth Item This is the fifth item
221
251
 
222
252
 
223
253
  ✓ Copied to Clipboard First Item
@@ -247,7 +277,8 @@ test('hot reload updates TUI when source file changes', async () => {
247
277
 
248
278
  try {
249
279
  // Wait for the extension to load
250
- await hotReloadSession.text({
280
+ await waitForTextWithDebug({
281
+ session: hotReloadSession,
251
282
  waitFor: (text) => /Hot Reload Test/i.test(text) && /Detail View/i.test(text),
252
283
  timeout: 5000,
253
284
  })
@@ -259,7 +290,8 @@ test('hot reload updates TUI when source file changes', async () => {
259
290
  await hotReloadSession.waitIdle()
260
291
 
261
292
  // Wait for the detail view to show
262
- await hotReloadSession.text({
293
+ await waitForTextWithDebug({
294
+ session: hotReloadSession,
263
295
  waitFor: (text) => /MARKER_VALUE/i.test(text),
264
296
  timeout: 10000,
265
297
  })
@@ -311,7 +343,8 @@ test('hot reload with navigation - preserves navigation and updates content', as
311
343
 
312
344
  try {
313
345
  // Wait for the extension to load
314
- await hotReloadSession.text({
346
+ await waitForTextWithDebug({
347
+ session: hotReloadSession,
315
348
  waitFor: (text) => /Hot Reload Test/i.test(text) && /List With Navigation/i.test(text),
316
349
  timeout: 10000,
317
350
  })
@@ -327,7 +360,8 @@ test('hot reload with navigation - preserves navigation and updates content', as
327
360
  await hotReloadSession.waitIdle()
328
361
 
329
362
  // Wait for the list to show OR the detail view (enter might auto-execute first action)
330
- await hotReloadSession.text({
363
+ await waitForTextWithDebug({
364
+ session: hotReloadSession,
331
365
  waitFor: (text) => /Item One/i.test(text),
332
366
  timeout: 10000,
333
367
  })
@@ -341,7 +375,8 @@ test('hot reload with navigation - preserves navigation and updates content', as
341
375
  await hotReloadSession.waitIdle()
342
376
 
343
377
  // Wait for the detail view with the marker
344
- await hotReloadSession.text({
378
+ await waitForTextWithDebug({
379
+ session: hotReloadSession,
345
380
  waitFor: (text) => /NAV_MARKER_VALUE/i.test(text) && /Item One Details/i.test(text),
346
381
  timeout: 10000,
347
382
  })
@@ -181,7 +181,7 @@ function ExtensionsList({
181
181
 
182
182
  export async function runHomeCommand(): Promise<void> {
183
183
  logger.log(`preparing to render the home command component`)
184
- await renderWithProviders(<Home />)
184
+ await renderWithProviders(<Home />, { extensionName: 'termcast-home' })
185
185
  logger.log(`rendered home command component`)
186
186
  }
187
187
 
@@ -41,9 +41,10 @@ function initializeReactRefresh() {
41
41
 
42
42
  // Only load react-refresh in non-production
43
43
  if (process.env.NODE_ENV !== 'production') {
44
- // Dynamic import to avoid bundling in production
45
- RefreshRuntime = require('react-refresh/runtime')
46
- initializeReactRefresh()
44
+ void import('react-refresh/runtime').then((runtime) => {
45
+ RefreshRuntime = runtime
46
+ initializeReactRefresh()
47
+ })
47
48
  }
48
49
 
49
50
  // Get captured renderer internals
package/src/index.tsx CHANGED
@@ -224,6 +224,7 @@ export { TermcastProvider } from 'termcast/src/internal/providers'
224
224
 
225
225
  // Helper function for rendering examples
226
226
  export { renderWithProviders } from 'termcast/src/utils'
227
+ export type { RenderWithProvidersOptions } from 'termcast/src/utils'
227
228
 
228
229
  // Window Management
229
230
  export { closeMainWindow, PopToRootType } from 'termcast/src/apis/window'