termcast 1.3.25 → 1.3.27

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 (49) hide show
  1. package/dist/apis/cache.d.ts.map +1 -1
  2. package/dist/apis/cache.js +17 -9
  3. package/dist/apis/cache.js.map +1 -1
  4. package/dist/apis/environment.d.ts.map +1 -1
  5. package/dist/apis/environment.js +6 -1
  6. package/dist/apis/environment.js.map +1 -1
  7. package/dist/apis/localstorage.d.ts.map +1 -1
  8. package/dist/apis/localstorage.js +11 -5
  9. package/dist/apis/localstorage.js.map +1 -1
  10. package/dist/cli.d.ts +1 -0
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +2 -0
  13. package/dist/cli.js.map +1 -1
  14. package/dist/compile.d.ts +2 -2
  15. package/dist/compile.d.ts.map +1 -1
  16. package/dist/compile.js +26 -6
  17. package/dist/compile.js.map +1 -1
  18. package/dist/examples/internal/text-stacking.js +5 -1
  19. package/dist/examples/internal/text-stacking.js.map +1 -1
  20. package/dist/examples/nested-navigation.js +2 -9
  21. package/dist/examples/nested-navigation.js.map +1 -1
  22. package/dist/examples/simple-navigation.js +2 -9
  23. package/dist/examples/simple-navigation.js.map +1 -1
  24. package/dist/extensions/dev.d.ts +3 -3
  25. package/dist/extensions/dev.d.ts.map +1 -1
  26. package/dist/extensions/dev.js +24 -15
  27. package/dist/extensions/dev.js.map +1 -1
  28. package/dist/extensions/home.d.ts.map +1 -1
  29. package/dist/extensions/home.js +2 -6
  30. package/dist/extensions/home.js.map +1 -1
  31. package/dist/internal/navigation.d.ts.map +1 -1
  32. package/dist/internal/navigation.js +12 -5
  33. package/dist/internal/navigation.js.map +1 -1
  34. package/dist/utils.d.ts.map +1 -1
  35. package/dist/utils.js +5 -1
  36. package/dist/utils.js.map +1 -1
  37. package/package.json +6 -3
  38. package/src/apis/cache.tsx +23 -15
  39. package/src/apis/environment.tsx +7 -1
  40. package/src/apis/localstorage.tsx +14 -7
  41. package/src/cli.tsx +3 -0
  42. package/src/compile.tsx +38 -10
  43. package/src/examples/internal/text-stacking.tsx +5 -1
  44. package/src/examples/nested-navigation.tsx +2 -14
  45. package/src/examples/simple-navigation.tsx +2 -14
  46. package/src/extensions/dev.tsx +27 -19
  47. package/src/extensions/home.tsx +2 -11
  48. package/src/internal/navigation.tsx +16 -10
  49. package/src/utils.tsx +5 -1
@@ -1,10 +1,7 @@
1
1
  import React from 'react'
2
- import { createRoot } from '@opentui/react'
3
- import { createCliRenderer } from '@opentui/core'
4
- import List from 'termcast'
2
+ import List, { renderWithProviders } from 'termcast'
5
3
  import { Action, ActionPanel } from 'termcast'
6
4
  import { useNavigation } from 'termcast/src/internal/navigation'
7
- import { TermcastProvider } from 'termcast/src/internal/providers'
8
5
 
9
6
  function ThirdLevel({ path }: { path: string[] }): any {
10
7
  const { pop } = useNavigation()
@@ -108,13 +105,4 @@ function FirstLevel(): any {
108
105
  )
109
106
  }
110
107
 
111
- function App(): any {
112
- return (
113
- <TermcastProvider>
114
- <FirstLevel />
115
- </TermcastProvider>
116
- )
117
- }
118
-
119
- const renderer = await createCliRenderer()
120
- createRoot(renderer).render(<App />)
108
+ await renderWithProviders(<FirstLevel />)
@@ -1,10 +1,7 @@
1
1
  import React from 'react'
2
- import { createRoot } from '@opentui/react'
3
- import { createCliRenderer } from '@opentui/core'
4
- import List from 'termcast'
2
+ import List, { renderWithProviders } from 'termcast'
5
3
  import { Action, ActionPanel } from 'termcast'
6
4
  import { useNavigation } from 'termcast/src/internal/navigation'
7
- import { TermcastProvider } from 'termcast/src/internal/providers'
8
5
 
9
6
  function GoBackAction(): any {
10
7
  const { pop } = useNavigation()
@@ -87,13 +84,4 @@ function MainView(): any {
87
84
  )
88
85
  }
89
86
 
90
- function App(): any {
91
- return (
92
- <TermcastProvider>
93
- <MainView />
94
- </TermcastProvider>
95
- )
96
- }
97
-
98
- const renderer = await createCliRenderer()
99
- createRoot(renderer).render(<App />)
87
+ await renderWithProviders(<MainView />)
@@ -9,7 +9,7 @@ import { useNavigation } from 'termcast/src/internal/navigation'
9
9
  import { TermcastProvider } from 'termcast/src/internal/providers'
10
10
  import { showToast, Toast } from 'termcast/src/apis/toast'
11
11
  import { Icon } from 'termcast'
12
- import { getCommandsWithFiles, CommandWithFile } from '../package-json'
12
+ import { getCommandsWithFiles, CommandWithFile, RaycastPackageJson } from '../package-json'
13
13
  import { buildExtensionCommands } from '../build'
14
14
  import {
15
15
  runCommand,
@@ -24,18 +24,15 @@ interface BundledCommand extends CommandWithFile {
24
24
  }
25
25
 
26
26
  function ExtensionCommandsList({
27
- extensionPath,
27
+ packageJson,
28
28
  commands,
29
29
  skipArgv,
30
30
  }: {
31
- extensionPath: string
31
+ packageJson: RaycastPackageJson
32
32
  commands: BundledCommand[]
33
33
  skipArgv?: number
34
34
  }): any {
35
35
  const { push } = useNavigation()
36
- const { packageJson } = getCommandsWithFiles({
37
- packageJsonPath: path.join(extensionPath, 'package.json'),
38
- })
39
36
 
40
37
  const visibleCommands = commands.filter((cmd) => cmd.mode !== 'menu-bar')
41
38
 
@@ -205,7 +202,7 @@ export async function startDevMode({
205
202
  extensionPath: resolvedPath,
206
203
  extensionPackageJson: packageJson,
207
204
  devElement: (
208
- <ExtensionCommandsList extensionPath={resolvedPath} commands={commands} skipArgv={skipArgv} />
205
+ <ExtensionCommandsList packageJson={packageJson} commands={commands} skipArgv={skipArgv} />
209
206
  ),
210
207
  devRebuildCount: 1,
211
208
  })
@@ -217,32 +214,39 @@ export async function startDevMode({
217
214
  return <TermcastProvider key={String(devRebuildCount)}>{devElement}</TermcastProvider>
218
215
  }
219
216
 
220
- const renderer = await createCliRenderer()
217
+ const renderer = await createCliRenderer({
218
+ onDestroy: () => {
219
+ process.exit(0)
220
+ },
221
+ })
221
222
  createRoot(renderer).render(<App />)
222
223
  }
223
224
 
224
225
  export async function startCompiledExtension({
225
- extensionPath,
226
+ packageJson,
226
227
  compiledCommands,
227
228
  skipArgv = 0,
228
229
  }: {
229
- extensionPath: string
230
+ packageJson: RaycastPackageJson
230
231
  compiledCommands: Array<{
231
232
  name: string
232
- bundledPath: string
233
233
  Component: (props: any) => any
234
234
  }>
235
235
  skipArgv?: number
236
236
  }): Promise<void> {
237
- const packageJsonPath = path.join(extensionPath, 'package.json')
238
- const { packageJson, commands: commandsMetadata } = getCommandsWithFiles({
239
- packageJsonPath,
240
- })
237
+ // Build command metadata from packageJson.commands
238
+ const commandsMetadata = (packageJson.commands || []).map((cmd) => ({
239
+ ...cmd,
240
+ filePath: '',
241
+ exists: true,
242
+ }))
241
243
 
242
244
  const commands: BundledCommand[] = compiledCommands.map((compiled) => {
243
245
  const metadata = commandsMetadata.find((cmd) => cmd.name === compiled.name)
244
246
  return {
245
247
  ...metadata!,
248
+ filePath: '',
249
+ exists: true,
246
250
  bundledPath: '',
247
251
  Component: compiled.Component,
248
252
  }
@@ -261,10 +265,10 @@ export async function startCompiledExtension({
261
265
 
262
266
  useStore.setState({
263
267
  ...useStore.getInitialState(),
264
- extensionPath,
268
+ extensionPath: '', // No filesystem path for compiled extensions
265
269
  extensionPackageJson: packageJson,
266
270
  devElement: (
267
- <ExtensionCommandsList extensionPath={extensionPath} commands={commands} skipArgv={skipArgv} />
271
+ <ExtensionCommandsList packageJson={packageJson} commands={commands} skipArgv={skipArgv} />
268
272
  ),
269
273
  devRebuildCount: 1,
270
274
  })
@@ -274,7 +278,11 @@ export async function startCompiledExtension({
274
278
  return <TermcastProvider>{devElement}</TermcastProvider>
275
279
  }
276
280
 
277
- const renderer = await createCliRenderer()
281
+ const renderer = await createCliRenderer({
282
+ onDestroy: () => {
283
+ process.exit(0)
284
+ },
285
+ })
278
286
  createRoot(renderer).render(<App />)
279
287
  }
280
288
 
@@ -301,7 +309,7 @@ export async function triggerRebuild({
301
309
  extensionPackageJson: packageJson,
302
310
  devElement: (
303
311
  <ExtensionCommandsList
304
- extensionPath={extensionPath}
312
+ packageJson={packageJson}
305
313
  commands={commands}
306
314
  />
307
315
  ),
@@ -1,12 +1,9 @@
1
1
  import fs from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import React from 'react'
4
- import { createRoot } from '@opentui/react'
5
- import { createCliRenderer } from '@opentui/core'
6
- import { List, logger, useStore } from 'termcast'
4
+ import { List, logger, useStore, renderWithProviders } from 'termcast'
7
5
  import { Action, ActionPanel } from 'termcast'
8
6
  import { useNavigation } from 'termcast/src/internal/navigation'
9
- import { TermcastProvider } from 'termcast/src/internal/providers'
10
7
  import { showToast, Toast } from 'termcast/src/apis/toast'
11
8
  import { Icon } from 'termcast'
12
9
  import { getStoredExtensions } from '../utils'
@@ -185,13 +182,7 @@ function ExtensionsList({
185
182
 
186
183
  export async function runHomeCommand(): Promise<void> {
187
184
  logger.log(`preparing to render the home command component`)
188
-
189
- const renderer = await createCliRenderer()
190
- createRoot(renderer).render(
191
- <TermcastProvider>
192
- <Home />
193
- </TermcastProvider>,
194
- )
185
+ await renderWithProviders(<Home />)
195
186
  logger.log(`rendered home command component`)
196
187
  }
197
188
 
@@ -8,7 +8,7 @@ import React, {
8
8
  startTransition,
9
9
  useTransition,
10
10
  } from 'react'
11
- import { useKeyboard } from '@opentui/react'
11
+ import { useKeyboard, useRenderer } from '@opentui/react'
12
12
  import { CommonProps } from 'termcast/src/utils'
13
13
  import { useStore, type NavigationStackItem } from 'termcast/src/state'
14
14
  import { useIsInFocus } from 'termcast/src/internal/focus-context'
@@ -117,18 +117,24 @@ export function NavigationProvider(props: NavigationProviderProps): any {
117
117
  )
118
118
 
119
119
  const inFocus = useIsInFocus()
120
+ const renderer = useRenderer()
120
121
 
121
- // Handle ESC key to pop navigation
122
+ // Handle ESC key to pop navigation or exit
122
123
  useKeyboard((evt) => {
123
124
  if (!inFocus) return
124
- if (evt.name === 'escape' && stack.length > 1) {
125
- logger.log(
126
- 'popping navigation',
127
- stack.length - 1,
128
- 'stack:',
129
- stack.map((item) => (item.element as any).type.name),
130
- )
131
- pop()
125
+ if (evt.name === 'escape') {
126
+ if (stack.length > 1) {
127
+ logger.log(
128
+ 'popping navigation',
129
+ stack.length - 1,
130
+ 'stack:',
131
+ stack.map((item) => (item.element as any).type.name),
132
+ )
133
+ pop()
134
+ } else {
135
+ // At root with no dialogs - exit the CLI
136
+ renderer.destroy()
137
+ }
132
138
  }
133
139
  })
134
140
 
package/src/utils.tsx CHANGED
@@ -14,7 +14,11 @@ import {
14
14
  import { logger } from './logger'
15
15
 
16
16
  export async function renderWithProviders(element: ReactNode): Promise<void> {
17
- const renderer = await createCliRenderer()
17
+ const renderer = await createCliRenderer({
18
+ onDestroy: () => {
19
+ process.exit(0)
20
+ },
21
+ })
18
22
  createRoot(renderer).render(<TermcastProvider>{element}</TermcastProvider>)
19
23
  }
20
24