termcast 1.4.1 → 1.6.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 (180) hide show
  1. package/dist/build.d.ts.map +1 -1
  2. package/dist/build.js +30 -12
  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/compile.d.ts.map +1 -1
  7. package/dist/compile.js +7 -1
  8. package/dist/compile.js.map +1 -1
  9. package/dist/components/bar-graph.d.ts +23 -8
  10. package/dist/components/bar-graph.d.ts.map +1 -1
  11. package/dist/components/bar-graph.js +84 -40
  12. package/dist/components/bar-graph.js.map +1 -1
  13. package/dist/components/dotted-line-graph.d.ts +86 -0
  14. package/dist/components/dotted-line-graph.d.ts.map +1 -0
  15. package/dist/components/dotted-line-graph.js +260 -0
  16. package/dist/components/dotted-line-graph.js.map +1 -0
  17. package/dist/components/extension-preferences.d.ts.map +1 -1
  18. package/dist/components/extension-preferences.js +1 -10
  19. package/dist/components/extension-preferences.js.map +1 -1
  20. package/dist/components/graph.d.ts.map +1 -1
  21. package/dist/components/graph.js +7 -1
  22. package/dist/components/graph.js.map +1 -1
  23. package/dist/components/histogram.d.ts +42 -0
  24. package/dist/components/histogram.d.ts.map +1 -0
  25. package/dist/components/histogram.js +115 -0
  26. package/dist/components/histogram.js.map +1 -0
  27. package/dist/components/horizontal-bar-graph.d.ts +47 -0
  28. package/dist/components/horizontal-bar-graph.d.ts.map +1 -0
  29. package/dist/components/horizontal-bar-graph.js +137 -0
  30. package/dist/components/horizontal-bar-graph.js.map +1 -0
  31. package/dist/components/list.d.ts +9 -0
  32. package/dist/components/list.d.ts.map +1 -1
  33. package/dist/components/list.js +84 -21
  34. package/dist/components/list.js.map +1 -1
  35. package/dist/examples/bar-graph-weekly.js +2 -2
  36. package/dist/examples/bar-graph-weekly.js.map +1 -1
  37. package/dist/examples/charts-showcase-barchart.d.ts +2 -0
  38. package/dist/examples/charts-showcase-barchart.d.ts.map +1 -0
  39. package/dist/examples/charts-showcase-barchart.js +10 -0
  40. package/dist/examples/charts-showcase-barchart.js.map +1 -0
  41. package/dist/examples/charts-showcase-bargraph.d.ts +2 -0
  42. package/dist/examples/charts-showcase-bargraph.d.ts.map +1 -0
  43. package/dist/examples/charts-showcase-bargraph.js +60 -0
  44. package/dist/examples/charts-showcase-bargraph.js.map +1 -0
  45. package/dist/examples/charts-showcase-candle.d.ts +2 -0
  46. package/dist/examples/charts-showcase-candle.d.ts.map +1 -0
  47. package/dist/examples/charts-showcase-candle.js +30 -0
  48. package/dist/examples/charts-showcase-candle.js.map +1 -0
  49. package/dist/examples/charts-showcase-graph.d.ts +2 -0
  50. package/dist/examples/charts-showcase-graph.d.ts.map +1 -0
  51. package/dist/examples/charts-showcase-graph.js +33 -0
  52. package/dist/examples/charts-showcase-graph.js.map +1 -0
  53. package/dist/examples/charts-showcase-heatmap.d.ts +2 -0
  54. package/dist/examples/charts-showcase-heatmap.d.ts.map +1 -0
  55. package/dist/examples/charts-showcase-heatmap.js +36 -0
  56. package/dist/examples/charts-showcase-heatmap.js.map +1 -0
  57. package/dist/examples/charts-showcase-mixed.d.ts +2 -0
  58. package/dist/examples/charts-showcase-mixed.d.ts.map +1 -0
  59. package/dist/examples/charts-showcase-mixed.js +30 -0
  60. package/dist/examples/charts-showcase-mixed.js.map +1 -0
  61. package/dist/examples/charts-showcase-progress.d.ts +2 -0
  62. package/dist/examples/charts-showcase-progress.d.ts.map +1 -0
  63. package/dist/examples/charts-showcase-progress.js +10 -0
  64. package/dist/examples/charts-showcase-progress.js.map +1 -0
  65. package/dist/examples/graph-multi-series.js +1 -1
  66. package/dist/examples/graph-multi-series.js.map +1 -1
  67. package/dist/examples/horizontal-bar-graph-weekly.d.ts +2 -0
  68. package/dist/examples/horizontal-bar-graph-weekly.d.ts.map +1 -0
  69. package/dist/examples/horizontal-bar-graph-weekly.js +67 -0
  70. package/dist/examples/horizontal-bar-graph-weekly.js.map +1 -0
  71. package/dist/examples/list-detail-height-ratchet.d.ts +2 -0
  72. package/dist/examples/list-detail-height-ratchet.d.ts.map +1 -0
  73. package/dist/examples/list-detail-height-ratchet.js +26 -0
  74. package/dist/examples/list-detail-height-ratchet.js.map +1 -0
  75. package/dist/examples/simple-dotted-line-graph.d.ts +2 -0
  76. package/dist/examples/simple-dotted-line-graph.d.ts.map +1 -0
  77. package/dist/examples/simple-dotted-line-graph.js +39 -0
  78. package/dist/examples/simple-dotted-line-graph.js.map +1 -0
  79. package/dist/examples/simple-histogram.d.ts +2 -0
  80. package/dist/examples/simple-histogram.d.ts.map +1 -0
  81. package/dist/examples/simple-histogram.js +47 -0
  82. package/dist/examples/simple-histogram.js.map +1 -0
  83. package/dist/extensions/dev.d.ts.map +1 -1
  84. package/dist/extensions/dev.js +1 -0
  85. package/dist/extensions/dev.js.map +1 -1
  86. package/dist/globals.js +8 -0
  87. package/dist/globals.js.map +1 -1
  88. package/dist/index.d.ts +6 -0
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +6 -0
  91. package/dist/index.js.map +1 -1
  92. package/dist/package-json.d.ts +2 -0
  93. package/dist/package-json.d.ts.map +1 -1
  94. package/dist/package-json.js +20 -17
  95. package/dist/package-json.js.map +1 -1
  96. package/dist/platform/node/sqlite.d.ts +6 -5
  97. package/dist/platform/node/sqlite.d.ts.map +1 -1
  98. package/dist/platform/node/sqlite.js +30 -14
  99. package/dist/platform/node/sqlite.js.map +1 -1
  100. package/dist/profiler.d.ts +2 -0
  101. package/dist/profiler.d.ts.map +1 -0
  102. package/dist/profiler.js +390 -0
  103. package/dist/profiler.js.map +1 -0
  104. package/dist/theme.d.ts.map +1 -1
  105. package/dist/theme.js +11 -9
  106. package/dist/theme.js.map +1 -1
  107. package/dist/utils/run-command.d.ts.map +1 -1
  108. package/dist/utils/run-command.js +8 -19
  109. package/dist/utils/run-command.js.map +1 -1
  110. package/dist/utils.d.ts +1 -19
  111. package/dist/utils.d.ts.map +1 -1
  112. package/dist/utils.js +1 -100
  113. package/dist/utils.js.map +1 -1
  114. package/package.json +18 -21
  115. package/src/build.tsx +38 -15
  116. package/src/cli.tsx +3 -40
  117. package/src/compile.tsx +9 -1
  118. package/src/compile.vitest.tsx +8 -8
  119. package/src/components/bar-graph.tsx +217 -111
  120. package/src/components/dotted-line-graph.tsx +407 -0
  121. package/src/components/extension-preferences.tsx +2 -12
  122. package/src/components/graph.tsx +5 -1
  123. package/src/components/histogram.tsx +228 -0
  124. package/src/components/horizontal-bar-graph.tsx +279 -0
  125. package/src/components/list.tsx +112 -26
  126. package/src/examples/action-shortcut.vitest.tsx +20 -20
  127. package/src/examples/actions-context.vitest.tsx +2 -2
  128. package/src/examples/bar-graph-weekly.tsx +2 -2
  129. package/src/examples/bar-graph-weekly.vitest.tsx +103 -102
  130. package/src/examples/charts-showcase-bargraph.tsx +103 -0
  131. package/src/examples/detail-metadata-showcase.vitest.tsx +12 -12
  132. package/src/examples/form-basic.vitest.tsx +11 -11
  133. package/src/examples/form-dropdown.vitest.tsx +11 -11
  134. package/src/examples/form-scroll.vitest.tsx +1 -1
  135. package/src/examples/form-tagpicker.vitest.tsx +11 -11
  136. package/src/examples/github.vitest.tsx +22 -31
  137. package/src/examples/graph-bar-chart.vitest.tsx +36 -36
  138. package/src/examples/graph-multi-series.tsx +1 -1
  139. package/src/examples/graph-polymarket.vitest.tsx +24 -24
  140. package/src/examples/graph-row.vitest.tsx +14 -14
  141. package/src/examples/graph-styles.vitest.tsx +77 -77
  142. package/src/examples/horizontal-bar-graph-weekly.tsx +138 -0
  143. package/src/examples/horizontal-bar-graph-weekly.vitest.tsx +164 -0
  144. package/src/examples/list-detail-height-ratchet.tsx +48 -0
  145. package/src/examples/list-detail-height-ratchet.vitest.tsx +161 -0
  146. package/src/examples/list-detail-metadata.vitest.tsx +51 -51
  147. package/src/examples/list-dropdown-default.vitest.tsx +27 -27
  148. package/src/examples/list-fetch-data.vitest.tsx +3 -3
  149. package/src/examples/list-loading-empty-view.vitest.tsx +1 -1
  150. package/src/examples/list-no-actions.vitest.tsx +3 -3
  151. package/src/examples/list-scrollbox.vitest.tsx +6 -6
  152. package/src/examples/list-spacing-mode.vitest.tsx +1 -1
  153. package/src/examples/list-with-detail.vitest.tsx +55 -55
  154. package/src/examples/list-with-dropdown.vitest.tsx +6 -6
  155. package/src/examples/list-with-sections.vitest.tsx +20 -20
  156. package/src/examples/list-with-toast.vitest.tsx +4 -4
  157. package/src/examples/simple-candle-chart.vitest.tsx +61 -59
  158. package/src/examples/simple-dotted-line-graph.tsx +53 -0
  159. package/src/examples/simple-dotted-line-graph.vitest.tsx +62 -0
  160. package/src/examples/simple-grid.vitest.tsx +4 -4
  161. package/src/examples/simple-heatmap.vitest.tsx +9 -9
  162. package/src/examples/simple-histogram.tsx +90 -0
  163. package/src/examples/simple-navigation.vitest.tsx +25 -25
  164. package/src/examples/simple-progress-bar.vitest.tsx +7 -7
  165. package/src/examples/swift-extension.vitest.tsx +5 -5
  166. package/src/examples/toast-action.vitest.tsx +4 -4
  167. package/src/extensions/dev.tsx +2 -1
  168. package/src/extensions/dev.vitest.tsx +17 -17
  169. package/src/globals.ts +9 -0
  170. package/src/index.tsx +21 -0
  171. package/src/package-json.tsx +24 -23
  172. package/src/platform/node/sqlite.ts +29 -13
  173. package/src/profiler.tsx +487 -0
  174. package/src/theme.tsx +11 -10
  175. package/src/utils/run-command.tsx +10 -19
  176. package/src/utils.tsx +0 -163
  177. package/src/examples/store.tsx +0 -4
  178. package/src/examples/store.vitest.tsx +0 -78
  179. package/src/extensions/home.tsx +0 -227
  180. package/src/extensions/store.tsx +0 -375
package/src/utils.tsx CHANGED
@@ -13,10 +13,6 @@ import {
13
13
  readFileSync,
14
14
  ensureDir,
15
15
  execCommand,
16
- readdirSync,
17
- rmSync,
18
- mkdirSync,
19
- cpSync,
20
16
  } from '#platform/runtime'
21
17
  import {
22
18
  parsePackageJson,
@@ -317,90 +313,11 @@ export function captureException(exception: unknown): void {
317
313
  console.error('[captureException] Exception captured:', exception)
318
314
  }
319
315
 
320
- export function getExtensionPath(extensionName: string): string {
321
- const storeDir = getStoreDirectory()
322
- return joinPath(storeDir, extensionName)
323
- }
324
-
325
- export function getExtensionPackageJsonPath(extensionName: string): string {
326
- return joinPath(getExtensionPath(extensionName), 'package.json')
327
- }
328
-
329
- export function getExtensionPackageJson(
330
- extensionName: string,
331
- ): RaycastPackageJson | null {
332
- const packageJsonPath = getExtensionPackageJsonPath(extensionName)
333
-
334
- if (!fileExists(packageJsonPath)) {
335
- return null
336
- }
337
-
338
- try {
339
- return parsePackageJson({ packageJsonPath })
340
- } catch (error) {
341
- console.error(`Failed to parse package.json for ${extensionName}:`, error)
342
- return null
343
- }
344
- }
345
-
346
316
  export interface ExtensionPreferencesInfo {
347
317
  hasPreferences: boolean
348
318
  hasRequiredPreferences: boolean
349
319
  }
350
320
 
351
- export function checkExtensionPreferences(
352
- extensionName: string,
353
- ): ExtensionPreferencesInfo {
354
- const packageJson = getExtensionPackageJson(extensionName)
355
-
356
- if (!packageJson) {
357
- return { hasPreferences: false, hasRequiredPreferences: false }
358
- }
359
-
360
- // Check for extension-wide preferences
361
- const hasExtensionPreferences =
362
- packageJson.preferences && packageJson.preferences.length > 0
363
-
364
- // Check if any command has preferences
365
- const commandsWithPreferences = (packageJson.commands || []).filter(
366
- (cmd) => cmd.preferences && cmd.preferences.length > 0,
367
- )
368
-
369
- const hasPreferences =
370
- hasExtensionPreferences || commandsWithPreferences.length > 0
371
-
372
- // Check for required extension-wide preferences
373
- const requiredExtensionPrefs = (packageJson.preferences || []).filter(
374
- (pref) => pref.required,
375
- )
376
-
377
- // Check if any command has required preferences
378
- const commandsWithRequiredPrefs = (packageJson.commands || []).filter(
379
- (cmd) => {
380
- const requiredPrefs = (cmd.preferences || []).filter(
381
- (pref) => pref.required,
382
- )
383
- return requiredPrefs.length > 0
384
- },
385
- )
386
-
387
- const hasRequiredPreferences =
388
- requiredExtensionPrefs.length > 0 || commandsWithRequiredPrefs.length > 0
389
-
390
- return { hasPreferences, hasRequiredPreferences }
391
- }
392
-
393
- // Store management types
394
- interface BundledCommand extends CommandWithFile {
395
- bundledPath: string
396
- }
397
-
398
- interface StoredExtension {
399
- name: string
400
- packageJsonPath: string
401
- commands: BundledCommand[]
402
- }
403
-
404
321
  export function resolveCommandPath({
405
322
  commandName,
406
323
  dir,
@@ -425,87 +342,7 @@ export function resolveCommandPath({
425
342
  return ''
426
343
  }
427
344
 
428
- export function getStoreDirectory(): string {
429
- const homeDir = homedir()
430
- const storeDir = joinPath(homeDir, '.termcast', 'store')
431
-
432
- // Ensure store directory exists
433
- ensureDir(storeDir)
434
-
435
- return storeDir
436
- }
437
-
438
- export function installExtension({
439
- extensionName,
440
- extensionSourcePath,
441
- }: {
442
- extensionName: string
443
- extensionSourcePath: string
444
- }): void {
445
- const storeDir = getStoreDirectory()
446
- const extensionDir = joinPath(storeDir, extensionName)
447
-
448
- if (fileExists(extensionDir)) {
449
- rmSync(extensionDir)
450
- }
451
-
452
- mkdirSync(extensionDir)
453
- cpSync(extensionSourcePath, extensionDir)
454
-
455
- logger.log(`Extension '${extensionName}' installed to ${extensionDir}`)
456
- }
457
-
458
- export function getStoredExtensions(): StoredExtension[] {
459
- const storeDir = getStoreDirectory()
460
- const extensions: StoredExtension[] = []
461
345
 
462
- if (!fileExists(storeDir)) {
463
- return extensions
464
- }
465
-
466
- const entries = readdirSync(storeDir)
467
-
468
- for (const entry of entries) {
469
- if (!entry.isDirectory()) continue
470
-
471
- const extensionDir = joinPath(storeDir, entry.name)
472
- const packageJsonPath = joinPath(extensionDir, 'package.json')
473
-
474
- if (!fileExists(packageJsonPath)) {
475
- logger.log(`Skipping ${entry.name}: no package.json found`)
476
- continue
477
- }
478
-
479
- try {
480
- const commandsData = getCommandsWithFiles({ packageJsonPath })
481
-
482
- // Map commands to bundled commands using the resolver
483
- const bundledCommands: BundledCommand[] = commandsData.commands.map(
484
- (command) => {
485
- const bundledPath = resolveCommandPath({
486
- commandName: command.name,
487
- dir: extensionDir,
488
- })
489
-
490
- return {
491
- ...command,
492
- bundledPath,
493
- }
494
- },
495
- )
496
-
497
- extensions.push({
498
- name: entry.name,
499
- packageJsonPath,
500
- commands: bundledCommands,
501
- })
502
- } catch (error: any) {
503
- logger.error(`Failed to load extension ${entry.name}:`, error.message)
504
- }
505
- }
506
-
507
- return extensions
508
- }
509
346
 
510
347
  export type ParseExecOutputHandler<T = any> = (args: { stdout: string }) => T
511
348
 
@@ -1,4 +0,0 @@
1
- import Store from '../extensions/store'
2
- import { renderWithProviders } from '../utils'
3
-
4
- await renderWithProviders(<Store />)
@@ -1,78 +0,0 @@
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/store.tsx'],
10
- cols: 80,
11
- rows: 30,
12
- })
13
- })
14
-
15
- afterEach(() => {
16
- session?.close()
17
- })
18
-
19
- test('Store extension - searching for spiceblow shows Database', async () => {
20
- // Wait for store interface to load
21
- const initialOutput = await session.text({
22
- waitFor: (text) => {
23
- // Wait until we see the store title
24
- return text.includes('Store - Install Extensions')
25
- },
26
- timeout: 15000,
27
- })
28
-
29
- // Verify the store interface loads
30
- expect(initialOutput).toContain('Store - Install Extensions')
31
-
32
- // Type "spiceblow" in the search bar
33
- await session.type('spiceblow')
34
-
35
- // Get the output after search, waiting for Database to appear
36
- // This will automatically wait for the API request to complete and results to show
37
- const afterSearchOutput = await session.text({
38
- waitFor: (text) => {
39
- return text.includes('Search, update, insert')
40
- },
41
- timeout: 15000,
42
- })
43
-
44
- // Store the snapshot after searching for spiceblow
45
- expect(afterSearchOutput).toMatchInlineSnapshot(`
46
- "
47
-
48
-
49
- Store - Install Extensions ───────────────────────────────────────────────
50
-
51
- > spiceblow
52
-
53
- ›Spiceblow - Sql Database Management Search, update, insert and delete rows
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
- ↵ view details ↑↓ navigate ^k actions :vim powered by termcast.app
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
- "
77
- `)
78
- }, 30000)
@@ -1,227 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
- import React from 'react'
4
- import { List, logger, useStore, renderWithProviders } from 'termcast'
5
- import { Action, ActionPanel } from 'termcast'
6
- import { useNavigation } from 'termcast/src/internal/navigation'
7
- import { showToast, Toast } from 'termcast/src/apis/toast'
8
- import { Icon } from 'termcast'
9
- import { getStoredExtensions } from '../utils'
10
- import Store from './store'
11
- import { ExtensionPreferences } from '../components/extension-preferences'
12
- import { runCommand, clearCommandArguments } from '../utils/run-command'
13
- import '../globals'
14
-
15
- interface ExtensionCommand {
16
- extensionName: string
17
- extensionTitle: string
18
- extensionDir?: string
19
- command: any
20
- bundledPath?: string
21
- loadComponent?: () => Promise<(props: any) => any>
22
- packageJson?: any
23
- }
24
-
25
- // Built-in extensions available globally
26
- const builtinExtensions: ExtensionCommand[] = [
27
- {
28
- extensionName: 'termcast-store',
29
- extensionTitle: 'Termcast Store',
30
- command: {
31
- name: 'store',
32
- title: 'Store - Install Extensions',
33
- description: 'Browse and install extensions from the Raycast Store',
34
- mode: 'view',
35
- icon: 'Store',
36
- },
37
- loadComponent: async () => Store,
38
- },
39
- ]
40
-
41
- function ExtensionsList({
42
- allCommands,
43
- initialSearchQuery = '',
44
- }: {
45
- allCommands: ExtensionCommand[]
46
- initialSearchQuery?: string
47
- }): any {
48
- const { push, replace } = useNavigation()
49
- const [searchText, setSearchText] = React.useState(initialSearchQuery)
50
-
51
- const handleCommandSelect = async (item: ExtensionCommand) => {
52
- clearCommandArguments()
53
-
54
- try {
55
- await runCommand({
56
- command: item.command,
57
- extensionName: item.extensionName,
58
- packageJson: item.packageJson,
59
- bundledPath: item.bundledPath,
60
- loadComponent: item.loadComponent,
61
- push,
62
- replace,
63
- })
64
- } catch (error: any) {
65
- await showToast({
66
- style: Toast.Style.Failure,
67
- title: 'Failed to load command',
68
- message: error.message || String(error),
69
- })
70
- }
71
- }
72
-
73
- // Group commands by extension
74
- const groupedByExtension = allCommands.reduce(
75
- (acc, cmd) => {
76
- if (!acc[cmd.extensionName]) {
77
- acc[cmd.extensionName] = {
78
- title: cmd.extensionTitle,
79
- commands: [],
80
- }
81
- }
82
- acc[cmd.extensionName].commands.push(cmd)
83
- return acc
84
- },
85
- {} as Record<string, { title: string; commands: ExtensionCommand[] }>,
86
- )
87
-
88
- return (
89
- <List
90
- navigationTitle='Installed Extensions'
91
- searchBarPlaceholder='Search commands...'
92
- filtering={true}
93
- onSearchTextChange={setSearchText}
94
- searchText={searchText}
95
- >
96
- {Object.entries(groupedByExtension).map(
97
- ([extensionName, { title, commands }]) => (
98
- <List.Section key={extensionName} title={title}>
99
- {commands.map((item) => (
100
- <List.Item
101
- key={`${item.extensionName}-${item.command.name}`}
102
- id={`${item.extensionName}-${item.command.name}`}
103
- title={item.command.title}
104
- subtitle={item.command.description}
105
- icon={
106
- item.command.icon
107
- ? Icon[item.command.icon as keyof typeof Icon]
108
- : undefined
109
- }
110
- accessories={
111
- item.command.mode ? [{ text: item.command.mode }] : []
112
- }
113
- keywords={[
114
- ...(item.command.keywords || []),
115
- item.extensionName,
116
- ]}
117
- actions={
118
- <ActionPanel>
119
- <Action
120
- title='Run Command'
121
- onAction={() => {
122
- handleCommandSelect(item)
123
- }}
124
- />
125
- <Action
126
- title='Configure Extension'
127
- onAction={() => {
128
- push(
129
- <ExtensionPreferences
130
- extensionName={item.extensionName}
131
- onSubmit={() => {
132
- handleCommandSelect(item)
133
- }}
134
- />,
135
- )
136
- }}
137
- />
138
- <Action
139
- title='Configure Command'
140
- onAction={() => {
141
- push(
142
- <ExtensionPreferences
143
- extensionName={item.extensionName}
144
- commandName={item.command.name}
145
- onSubmit={() => {
146
- handleCommandSelect(item)
147
- }}
148
- />,
149
- )
150
- }}
151
- />
152
- {item.bundledPath && (
153
- <Action.CopyToClipboard
154
- content={item.bundledPath}
155
- title='Copy Bundle Path'
156
- />
157
- )}
158
- <Action.CopyToClipboard
159
- content={JSON.stringify(item.command, null, 2)}
160
- title='Copy Command Info'
161
- />
162
- </ActionPanel>
163
- }
164
- />
165
- ))}
166
- </List.Section>
167
- ),
168
- )}
169
-
170
- {allCommands.length === 0 && (
171
- <List.Section title='No Commands'>
172
- <List.Item
173
- title='No extensions installed'
174
- subtitle='Use "termcast build" to install an extension'
175
- />
176
- </List.Section>
177
- )}
178
- </List>
179
- )
180
- }
181
-
182
- export async function runHomeCommand(): Promise<void> {
183
- logger.log(`preparing to render the home command component`)
184
- await renderWithProviders(<Home />, { extensionName: 'termcast-home' })
185
- logger.log(`rendered home command component`)
186
- }
187
-
188
- export default function Home({
189
- initialSearchQuery = '',
190
- key,
191
- }: {
192
- initialSearchQuery?: string
193
- key?: React.Key
194
- }): any {
195
- const storedExtensions = getStoredExtensions()
196
-
197
- const allCommands: ExtensionCommand[] = []
198
-
199
- allCommands.push(...builtinExtensions)
200
-
201
- for (const extension of storedExtensions) {
202
- const packageJson = JSON.parse(
203
- fs.readFileSync(extension.packageJsonPath, 'utf-8'),
204
- )
205
- const extensionPath = path.dirname(extension.packageJsonPath)
206
-
207
- for (const command of extension.commands) {
208
- if (command.bundledPath) {
209
- allCommands.push({
210
- extensionName: extension.name,
211
- extensionTitle: packageJson.title || extension.name,
212
- extensionDir: extensionPath,
213
- command,
214
- bundledPath: command.bundledPath,
215
- packageJson,
216
- })
217
- }
218
- }
219
- }
220
-
221
- return (
222
- <ExtensionsList
223
- allCommands={allCommands}
224
- initialSearchQuery={initialSearchQuery}
225
- />
226
- )
227
- }