termcast 1.3.30 → 1.3.32
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.
- package/dist/apis/cache.d.ts.map +1 -1
- package/dist/apis/cache.js +4 -39
- package/dist/apis/cache.js.map +1 -1
- package/dist/apis/hud.d.ts.map +1 -1
- package/dist/apis/hud.js +13 -31
- package/dist/apis/hud.js.map +1 -1
- package/dist/apis/localstorage.d.ts.map +1 -1
- package/dist/apis/localstorage.js +3 -27
- package/dist/apis/localstorage.js.map +1 -1
- package/dist/apis/toast.d.ts +16 -43
- package/dist/apis/toast.d.ts.map +1 -1
- package/dist/apis/toast.js +78 -177
- package/dist/apis/toast.js.map +1 -1
- package/dist/build.d.ts +3 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +52 -2
- package/dist/build.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +206 -25
- package/dist/cli.js.map +1 -1
- package/dist/colors.d.ts.map +1 -1
- package/dist/colors.js +1 -0
- package/dist/colors.js.map +1 -1
- package/dist/compile.d.ts +0 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +18 -23
- package/dist/compile.js.map +1 -1
- package/dist/components/actions.d.ts.map +1 -1
- package/dist/components/actions.js +30 -15
- package/dist/components/actions.js.map +1 -1
- package/dist/components/animation-tick.d.ts +12 -0
- package/dist/components/animation-tick.d.ts.map +1 -0
- package/dist/components/animation-tick.js +63 -0
- package/dist/components/animation-tick.js.map +1 -0
- package/dist/components/detail.d.ts.map +1 -1
- package/dist/components/detail.js +10 -13
- package/dist/components/detail.js.map +1 -1
- package/dist/components/dropdown.d.ts +1 -0
- package/dist/components/dropdown.d.ts.map +1 -1
- package/dist/components/dropdown.js +27 -26
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/extension-preferences.d.ts.map +1 -1
- package/dist/components/extension-preferences.js +15 -10
- package/dist/components/extension-preferences.js.map +1 -1
- package/dist/components/footer.d.ts +13 -0
- package/dist/components/footer.d.ts.map +1 -0
- package/dist/components/footer.js +106 -0
- package/dist/components/footer.js.map +1 -0
- package/dist/components/form/file-autocomplete.d.ts +19 -4
- package/dist/components/form/file-autocomplete.d.ts.map +1 -1
- package/dist/components/form/file-autocomplete.js +56 -55
- package/dist/components/form/file-autocomplete.js.map +1 -1
- package/dist/components/form/file-picker.d.ts.map +1 -1
- package/dist/components/form/file-picker.js +26 -15
- package/dist/components/form/file-picker.js.map +1 -1
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/index.js +17 -15
- package/dist/components/form/index.js.map +1 -1
- package/dist/components/form/with-left-border.d.ts.map +1 -1
- package/dist/components/form/with-left-border.js +4 -12
- package/dist/components/form/with-left-border.js.map +1 -1
- package/dist/components/list.d.ts.map +1 -1
- package/dist/components/list.js +126 -86
- package/dist/components/list.js.map +1 -1
- package/dist/components/loading-bar.d.ts.map +1 -1
- package/dist/components/loading-bar.js +5 -22
- package/dist/components/loading-bar.js.map +1 -1
- package/dist/components/loading-text.d.ts.map +1 -1
- package/dist/components/loading-text.js +3 -22
- package/dist/components/loading-text.js.map +1 -1
- package/dist/components/theme-picker.d.ts +2 -0
- package/dist/components/theme-picker.d.ts.map +1 -0
- package/dist/components/theme-picker.js +37 -0
- package/dist/components/theme-picker.js.map +1 -0
- package/dist/descendants.d.ts +6 -0
- package/dist/descendants.d.ts.map +1 -1
- package/dist/descendants.js +74 -8
- package/dist/descendants.js.map +1 -1
- package/dist/examples/internal/descendants-rerender.d.ts +14 -0
- package/dist/examples/internal/descendants-rerender.d.ts.map +1 -0
- package/dist/examples/internal/descendants-rerender.js +145 -0
- package/dist/examples/internal/descendants-rerender.js.map +1 -0
- package/dist/examples/internal/simple-dialog.js +4 -1
- package/dist/examples/internal/simple-dialog.js.map +1 -1
- package/dist/examples/internal/simple-scrollbox.js +1 -1
- package/dist/examples/internal/simple-scrollbox.js.map +1 -1
- package/dist/examples/list-with-dropdown.js +1 -1
- package/dist/examples/list-with-dropdown.js.map +1 -1
- package/dist/examples/miscellaneous.js +1 -1
- package/dist/examples/miscellaneous.js.map +1 -1
- package/dist/examples/toast-action.d.ts +2 -0
- package/dist/examples/toast-action.d.ts.map +1 -0
- package/dist/examples/toast-action.js +76 -0
- package/dist/examples/toast-action.js.map +1 -0
- package/dist/examples/toast-variations.js +38 -36
- package/dist/examples/toast-variations.js.map +1 -1
- package/dist/extensions/dev.d.ts +1 -1
- package/dist/extensions/dev.d.ts.map +1 -1
- package/dist/extensions/dev.js +62 -30
- package/dist/extensions/dev.js.map +1 -1
- package/dist/extensions/home.d.ts.map +1 -1
- package/dist/extensions/home.js +4 -3
- package/dist/extensions/home.js.map +1 -1
- package/dist/extensions/react-refresh-init.d.ts +5 -0
- package/dist/extensions/react-refresh-init.d.ts.map +1 -0
- package/dist/extensions/react-refresh-init.js +52 -0
- package/dist/extensions/react-refresh-init.js.map +1 -0
- package/dist/internal/date-picker-widget.js +1 -1
- package/dist/internal/date-picker-widget.js.map +1 -1
- package/dist/internal/dialog.d.ts +8 -3
- package/dist/internal/dialog.d.ts.map +1 -1
- package/dist/internal/dialog.js +37 -53
- package/dist/internal/dialog.js.map +1 -1
- package/dist/internal/navigation.d.ts +1 -0
- package/dist/internal/navigation.d.ts.map +1 -1
- package/dist/internal/navigation.js +25 -1
- package/dist/internal/navigation.js.map +1 -1
- package/dist/internal/providers.d.ts.map +1 -1
- package/dist/internal/providers.js +9 -197
- package/dist/internal/providers.js.map +1 -1
- package/dist/internal/scrollbox.d.ts.map +1 -1
- package/dist/internal/scrollbox.js +1 -0
- package/dist/internal/scrollbox.js.map +1 -1
- package/dist/release.d.ts +1 -0
- package/dist/release.d.ts.map +1 -1
- package/dist/release.js +16 -9
- package/dist/release.js.map +1 -1
- package/dist/state.d.ts +27 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +6 -0
- package/dist/state.js.map +1 -1
- package/dist/theme.d.ts +6 -19
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +76 -45
- package/dist/theme.js.map +1 -1
- package/dist/themes/aura.json +69 -0
- package/dist/themes/ayu.json +80 -0
- package/dist/themes/catppuccin-frappe.json +233 -0
- package/dist/themes/catppuccin-macchiato.json +233 -0
- package/dist/themes/catppuccin.json +112 -0
- package/dist/themes/cobalt2.json +228 -0
- package/dist/themes/cursor.json +249 -0
- package/dist/themes/dracula.json +219 -0
- package/dist/themes/everforest.json +241 -0
- package/dist/themes/flexoki.json +237 -0
- package/dist/themes/github-light.json +56 -0
- package/dist/themes/github.json +241 -0
- package/dist/themes/gruvbox.json +95 -0
- package/dist/themes/kanagawa.json +77 -0
- package/dist/themes/lucent-orng.json +227 -0
- package/dist/themes/material.json +235 -0
- package/dist/themes/matrix.json +77 -0
- package/dist/themes/mercury.json +245 -0
- package/dist/themes/monokai.json +221 -0
- package/dist/themes/nightowl.json +221 -0
- package/dist/themes/nord.json +223 -0
- package/dist/themes/one-dark.json +84 -0
- package/dist/themes/opencode-light.json +62 -0
- package/dist/themes/opencode.json +245 -0
- package/dist/themes/orng.json +245 -0
- package/dist/themes/palenight.json +222 -0
- package/dist/themes/rosepine.json +234 -0
- package/dist/themes/solarized.json +223 -0
- package/dist/themes/synthwave84.json +226 -0
- package/dist/themes/termcast.json +226 -0
- package/dist/themes/tokyonight.json +243 -0
- package/dist/themes/vercel.json +255 -0
- package/dist/themes/vesper.json +218 -0
- package/dist/themes/zenburn.json +223 -0
- package/dist/themes.d.ts +57 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/themes.js +181 -0
- package/dist/themes.js.map +1 -0
- package/dist/utils/run-command.d.ts +2 -1
- package/dist/utils/run-command.d.ts.map +1 -1
- package/dist/utils/run-command.js +20 -10
- package/dist/utils/run-command.js.map +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +90 -17
- package/dist/utils.js.map +1 -1
- package/dist/watcher.d.ts +3 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +16 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +16 -10
- package/src/apis/cache.tsx +5 -44
- package/src/apis/hud.tsx +17 -62
- package/src/apis/localstorage.tsx +3 -32
- package/src/apis/toast.tsx +91 -275
- package/src/build.test.tsx +10 -0
- package/src/build.tsx +61 -1
- package/src/cli.tsx +365 -103
- package/src/colors.tsx +1 -0
- package/src/compile.tsx +21 -29
- package/src/compile.vitest.tsx +300 -0
- package/src/components/actions.tsx +64 -45
- package/src/components/animation-tick.tsx +85 -0
- package/src/components/detail.tsx +31 -35
- package/src/components/dropdown.tsx +32 -21
- package/src/components/extension-preferences.tsx +14 -10
- package/src/components/footer.tsx +241 -0
- package/src/components/form/file-autocomplete.tsx +80 -60
- package/src/components/form/file-picker.tsx +37 -25
- package/src/components/form/index.tsx +45 -41
- package/src/components/form/with-left-border.tsx +4 -14
- package/src/components/list.tsx +181 -121
- package/src/components/loading-bar.tsx +5 -25
- package/src/components/loading-text.tsx +4 -23
- package/src/components/theme-picker.tsx +57 -0
- package/src/descendants.tsx +98 -9
- package/src/examples/actions-dialog-layout.vitest.tsx +112 -0
- package/src/examples/file-autocomplete.vitest.tsx +131 -122
- package/src/examples/form-basic.vitest.tsx +463 -644
- package/src/examples/form-dropdown.vitest.tsx +553 -571
- package/src/examples/form-scroll.vitest.tsx +112 -102
- package/src/examples/form-tagpicker.vitest.tsx +364 -338
- package/src/examples/internal/descendants-rerender.tsx +273 -0
- package/src/examples/internal/descendants-rerender.vitest.tsx +194 -0
- package/src/examples/internal/simple-dialog.tsx +4 -4
- package/src/examples/internal/simple-scrollbox.tsx +2 -2
- package/src/examples/internal/simple-scrollbox.vitest.tsx +43 -31
- package/src/examples/list-detail-metadata.vitest.tsx +34 -30
- package/src/examples/list-dropdown-default.vitest.tsx +84 -72
- package/src/examples/list-empty-view.vitest.tsx +93 -0
- package/src/examples/list-fetch-data.vitest.tsx +36 -30
- package/src/examples/list-scrollbox.vitest.tsx +59 -39
- package/src/examples/list-with-detail.vitest.tsx +339 -314
- package/src/examples/list-with-dropdown.tsx +1 -0
- package/src/examples/list-with-dropdown.vitest.tsx +176 -150
- package/src/examples/list-with-sections.vitest.tsx +289 -270
- package/src/examples/list-with-toast.vitest.tsx +44 -44
- package/src/examples/miscellaneous.tsx +10 -0
- package/src/examples/simple-file-picker.vitest.tsx +90 -86
- package/src/examples/simple-grid.vitest.tsx +275 -249
- package/src/examples/simple-navigation.vitest.tsx +192 -168
- package/src/examples/store.vitest.tsx +6 -4
- package/src/examples/swift-extension.vitest.tsx +31 -19
- package/src/examples/synonyms.vitest.tsx +93 -83
- package/src/examples/toast-action.tsx +160 -0
- package/src/examples/toast-action.vitest.tsx +404 -0
- package/src/examples/toast-variations.tsx +58 -57
- package/src/examples/toast-variations.vitest.tsx +186 -166
- package/src/extensions/dev.tsx +74 -33
- package/src/extensions/dev.vitest.tsx +162 -69
- package/src/extensions/home.tsx +5 -6
- package/src/extensions/react-refresh-init.tsx +59 -0
- package/src/internal/date-picker-widget.tsx +1 -1
- package/src/internal/dialog.tsx +59 -83
- package/src/internal/navigation.tsx +37 -4
- package/src/internal/providers.tsx +27 -315
- package/src/internal/scrollbox.tsx +1 -0
- package/src/release.tsx +16 -10
- package/src/state.tsx +36 -3
- package/src/theme.tsx +82 -51
- package/src/themes/aura.json +69 -0
- package/src/themes/ayu.json +80 -0
- package/src/themes/catppuccin-frappe.json +233 -0
- package/src/themes/catppuccin-macchiato.json +233 -0
- package/src/themes/catppuccin.json +112 -0
- package/src/themes/cobalt2.json +228 -0
- package/src/themes/cursor.json +249 -0
- package/src/themes/dracula.json +219 -0
- package/src/themes/everforest.json +241 -0
- package/src/themes/flexoki.json +237 -0
- package/src/themes/github-light.json +56 -0
- package/src/themes/github.json +241 -0
- package/src/themes/gruvbox.json +95 -0
- package/src/themes/kanagawa.json +77 -0
- package/src/themes/lucent-orng.json +227 -0
- package/src/themes/material.json +235 -0
- package/src/themes/matrix.json +77 -0
- package/src/themes/mercury.json +252 -0
- package/src/themes/monokai.json +221 -0
- package/src/themes/nightowl.json +221 -0
- package/src/themes/nord.json +223 -0
- package/src/themes/one-dark.json +84 -0
- package/src/themes/opencode-light.json +62 -0
- package/src/themes/opencode.json +245 -0
- package/src/themes/orng.json +245 -0
- package/src/themes/palenight.json +222 -0
- package/src/themes/rosepine.json +234 -0
- package/src/themes/solarized.json +223 -0
- package/src/themes/synthwave84.json +226 -0
- package/src/themes/termcast.json +227 -0
- package/src/themes/tokyonight.json +243 -0
- package/src/themes/vercel.json +255 -0
- package/src/themes/vesper.json +218 -0
- package/src/themes/zenburn.json +223 -0
- package/src/themes.ts +291 -0
- package/src/utils/run-command.tsx +23 -12
- package/src/utils.tsx +115 -18
- package/src/watcher.tsx +19 -0
package/src/themes.ts
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
// Theme resolver for termcast
|
|
2
|
+
// Adapted from https://github.com/sst/opencode
|
|
3
|
+
|
|
4
|
+
import { parseColor, RGBA } from '@opentui/core'
|
|
5
|
+
|
|
6
|
+
import aura from './themes/aura.json'
|
|
7
|
+
import ayu from './themes/ayu.json'
|
|
8
|
+
import catppuccin from './themes/catppuccin.json'
|
|
9
|
+
import catppuccinFrappe from './themes/catppuccin-frappe.json'
|
|
10
|
+
import catppuccinMacchiato from './themes/catppuccin-macchiato.json'
|
|
11
|
+
import cobalt2 from './themes/cobalt2.json'
|
|
12
|
+
import cursor from './themes/cursor.json'
|
|
13
|
+
import dracula from './themes/dracula.json'
|
|
14
|
+
import everforest from './themes/everforest.json'
|
|
15
|
+
import flexoki from './themes/flexoki.json'
|
|
16
|
+
import github from './themes/github.json'
|
|
17
|
+
import githubLight from './themes/github-light.json'
|
|
18
|
+
import gruvbox from './themes/gruvbox.json'
|
|
19
|
+
import kanagawa from './themes/kanagawa.json'
|
|
20
|
+
import material from './themes/material.json'
|
|
21
|
+
import matrix from './themes/matrix.json'
|
|
22
|
+
import mercury from './themes/mercury.json'
|
|
23
|
+
import monokai from './themes/monokai.json'
|
|
24
|
+
import nightowl from './themes/nightowl.json'
|
|
25
|
+
import nord from './themes/nord.json'
|
|
26
|
+
import oneDark from './themes/one-dark.json'
|
|
27
|
+
import opencode from './themes/opencode.json'
|
|
28
|
+
import opencodeLight from './themes/opencode-light.json'
|
|
29
|
+
import orng from './themes/orng.json'
|
|
30
|
+
import palenight from './themes/palenight.json'
|
|
31
|
+
import rosepine from './themes/rosepine.json'
|
|
32
|
+
import solarized from './themes/solarized.json'
|
|
33
|
+
import synthwave84 from './themes/synthwave84.json'
|
|
34
|
+
import termcast from './themes/termcast.json'
|
|
35
|
+
import tokyonight from './themes/tokyonight.json'
|
|
36
|
+
import vercel from './themes/vercel.json'
|
|
37
|
+
import vesper from './themes/vesper.json'
|
|
38
|
+
import zenburn from './themes/zenburn.json'
|
|
39
|
+
|
|
40
|
+
type HexColor = `#${string}`
|
|
41
|
+
type RefName = string
|
|
42
|
+
type Variant = {
|
|
43
|
+
dark: HexColor | RefName
|
|
44
|
+
light: HexColor | RefName
|
|
45
|
+
}
|
|
46
|
+
type ColorValue = HexColor | RefName | Variant
|
|
47
|
+
|
|
48
|
+
interface ThemeJson {
|
|
49
|
+
$schema?: string
|
|
50
|
+
defs?: Record<string, HexColor | RefName>
|
|
51
|
+
theme: Record<string, ColorValue>
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ResolvedTheme {
|
|
55
|
+
// Text colors
|
|
56
|
+
text: string
|
|
57
|
+
textMuted: string
|
|
58
|
+
|
|
59
|
+
// Background colors
|
|
60
|
+
background: string
|
|
61
|
+
backgroundPanel: string
|
|
62
|
+
backgroundElement: string
|
|
63
|
+
|
|
64
|
+
// Primary/accent colors
|
|
65
|
+
primary: string
|
|
66
|
+
secondary: string
|
|
67
|
+
accent: string
|
|
68
|
+
|
|
69
|
+
// Semantic colors
|
|
70
|
+
info: string
|
|
71
|
+
success: string
|
|
72
|
+
warning: string
|
|
73
|
+
error: string
|
|
74
|
+
|
|
75
|
+
// Border colors
|
|
76
|
+
border: string
|
|
77
|
+
borderActive: string
|
|
78
|
+
borderSubtle: string
|
|
79
|
+
|
|
80
|
+
// Diff colors
|
|
81
|
+
diffAdded: string
|
|
82
|
+
diffRemoved: string
|
|
83
|
+
diffContext: string
|
|
84
|
+
diffHunkHeader: string
|
|
85
|
+
diffHighlightAdded: string
|
|
86
|
+
diffHighlightRemoved: string
|
|
87
|
+
diffAddedBg: string
|
|
88
|
+
diffRemovedBg: string
|
|
89
|
+
diffContextBg: string
|
|
90
|
+
diffLineNumber: string
|
|
91
|
+
diffAddedLineNumberBg: string
|
|
92
|
+
diffRemovedLineNumberBg: string
|
|
93
|
+
|
|
94
|
+
// Markdown colors
|
|
95
|
+
markdownText: string
|
|
96
|
+
markdownHeading: string
|
|
97
|
+
markdownLink: string
|
|
98
|
+
markdownLinkText: string
|
|
99
|
+
markdownCode: string
|
|
100
|
+
markdownBlockQuote: string
|
|
101
|
+
markdownEmph: string
|
|
102
|
+
markdownStrong: string
|
|
103
|
+
markdownHorizontalRule: string
|
|
104
|
+
markdownListItem: string
|
|
105
|
+
markdownListEnumeration: string
|
|
106
|
+
markdownImage: string
|
|
107
|
+
markdownImageText: string
|
|
108
|
+
markdownCodeBlock: string
|
|
109
|
+
|
|
110
|
+
// Syntax colors
|
|
111
|
+
syntaxComment: string
|
|
112
|
+
syntaxKeyword: string
|
|
113
|
+
syntaxFunction: string
|
|
114
|
+
syntaxVariable: string
|
|
115
|
+
syntaxString: string
|
|
116
|
+
syntaxNumber: string
|
|
117
|
+
syntaxType: string
|
|
118
|
+
syntaxOperator: string
|
|
119
|
+
syntaxPunctuation: string
|
|
120
|
+
|
|
121
|
+
// Transparent
|
|
122
|
+
transparent: undefined
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Note: lucent-orng excluded because it uses transparent backgrounds
|
|
126
|
+
const DEFAULT_THEMES: Record<string, ThemeJson> = {
|
|
127
|
+
aura,
|
|
128
|
+
ayu,
|
|
129
|
+
catppuccin,
|
|
130
|
+
'catppuccin-frappe': catppuccinFrappe,
|
|
131
|
+
'catppuccin-macchiato': catppuccinMacchiato,
|
|
132
|
+
cobalt2,
|
|
133
|
+
cursor,
|
|
134
|
+
dracula,
|
|
135
|
+
everforest,
|
|
136
|
+
flexoki,
|
|
137
|
+
github,
|
|
138
|
+
'github-light': githubLight,
|
|
139
|
+
gruvbox,
|
|
140
|
+
kanagawa,
|
|
141
|
+
material,
|
|
142
|
+
matrix,
|
|
143
|
+
mercury,
|
|
144
|
+
monokai,
|
|
145
|
+
nightowl,
|
|
146
|
+
nord,
|
|
147
|
+
'one-dark': oneDark,
|
|
148
|
+
opencode,
|
|
149
|
+
'opencode-light': opencodeLight,
|
|
150
|
+
orng,
|
|
151
|
+
palenight,
|
|
152
|
+
rosepine,
|
|
153
|
+
solarized,
|
|
154
|
+
synthwave84,
|
|
155
|
+
termcast,
|
|
156
|
+
tokyonight,
|
|
157
|
+
vercel,
|
|
158
|
+
vesper,
|
|
159
|
+
zenburn,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function rgbaToHex(rgba: RGBA): string {
|
|
163
|
+
const r = Math.round(rgba.r * 255)
|
|
164
|
+
.toString(16)
|
|
165
|
+
.padStart(2, '0')
|
|
166
|
+
const g = Math.round(rgba.g * 255)
|
|
167
|
+
.toString(16)
|
|
168
|
+
.padStart(2, '0')
|
|
169
|
+
const b = Math.round(rgba.b * 255)
|
|
170
|
+
.toString(16)
|
|
171
|
+
.padStart(2, '0')
|
|
172
|
+
return `#${r}${g}${b}`
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function resolveTheme(
|
|
176
|
+
themeJson: ThemeJson,
|
|
177
|
+
mode: 'dark' | 'light',
|
|
178
|
+
): ResolvedTheme {
|
|
179
|
+
const defs = themeJson.defs ?? {}
|
|
180
|
+
|
|
181
|
+
function resolveColorToHex(c: ColorValue): string {
|
|
182
|
+
if (typeof c === 'string') {
|
|
183
|
+
if (c === 'transparent' || c === 'none') {
|
|
184
|
+
return '#000000'
|
|
185
|
+
}
|
|
186
|
+
if (c.startsWith('#')) {
|
|
187
|
+
return c
|
|
188
|
+
}
|
|
189
|
+
// Reference to defs
|
|
190
|
+
if (defs[c] != null) {
|
|
191
|
+
return resolveColorToHex(defs[c] as ColorValue)
|
|
192
|
+
}
|
|
193
|
+
// Reference to another theme property
|
|
194
|
+
if (themeJson.theme[c] !== undefined) {
|
|
195
|
+
return resolveColorToHex(themeJson.theme[c] as ColorValue)
|
|
196
|
+
}
|
|
197
|
+
// Fallback
|
|
198
|
+
return '#808080'
|
|
199
|
+
}
|
|
200
|
+
// Variant with dark/light
|
|
201
|
+
return resolveColorToHex(c[mode])
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const t = themeJson.theme
|
|
205
|
+
const fallbackGray = '#808080'
|
|
206
|
+
const fallbackBg = '#1e1e1e'
|
|
207
|
+
const fallbackText = '#d4d4d4'
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
// Text
|
|
211
|
+
text: resolveColorToHex(t.text ?? fallbackText),
|
|
212
|
+
textMuted: resolveColorToHex(t.textMuted ?? fallbackGray),
|
|
213
|
+
|
|
214
|
+
// Background
|
|
215
|
+
background: resolveColorToHex(t.background ?? fallbackBg),
|
|
216
|
+
backgroundPanel: resolveColorToHex(t.backgroundPanel ?? fallbackBg),
|
|
217
|
+
backgroundElement: resolveColorToHex(t.backgroundElement ?? fallbackBg),
|
|
218
|
+
|
|
219
|
+
// Primary/accent
|
|
220
|
+
primary: resolveColorToHex(t.primary ?? fallbackGray),
|
|
221
|
+
secondary: resolveColorToHex(t.secondary ?? t.primary ?? fallbackGray),
|
|
222
|
+
accent: resolveColorToHex(t.accent ?? t.primary ?? fallbackGray),
|
|
223
|
+
|
|
224
|
+
// Semantic
|
|
225
|
+
info: resolveColorToHex(t.info ?? t.primary ?? fallbackGray),
|
|
226
|
+
success: resolveColorToHex(t.success ?? fallbackGray),
|
|
227
|
+
warning: resolveColorToHex(t.warning ?? fallbackGray),
|
|
228
|
+
error: resolveColorToHex(t.error ?? '#ff0000'),
|
|
229
|
+
|
|
230
|
+
// Border
|
|
231
|
+
border: resolveColorToHex(t.border ?? fallbackGray),
|
|
232
|
+
borderActive: resolveColorToHex(t.borderActive ?? t.primary ?? fallbackGray),
|
|
233
|
+
borderSubtle: resolveColorToHex(t.borderSubtle ?? fallbackBg),
|
|
234
|
+
|
|
235
|
+
// Diff
|
|
236
|
+
diffAdded: resolveColorToHex(t.diffAdded ?? '#4fd6be'),
|
|
237
|
+
diffRemoved: resolveColorToHex(t.diffRemoved ?? '#c53b53'),
|
|
238
|
+
diffContext: resolveColorToHex(t.diffContext ?? fallbackGray),
|
|
239
|
+
diffHunkHeader: resolveColorToHex(t.diffHunkHeader ?? fallbackGray),
|
|
240
|
+
diffHighlightAdded: resolveColorToHex(t.diffHighlightAdded ?? '#b8db87'),
|
|
241
|
+
diffHighlightRemoved: resolveColorToHex(t.diffHighlightRemoved ?? '#e26a75'),
|
|
242
|
+
diffAddedBg: resolveColorToHex(t.diffAddedBg ?? '#1e3a1e'),
|
|
243
|
+
diffRemovedBg: resolveColorToHex(t.diffRemovedBg ?? '#3a1e1e'),
|
|
244
|
+
diffContextBg: resolveColorToHex(t.diffContextBg ?? fallbackBg),
|
|
245
|
+
diffLineNumber: resolveColorToHex(t.diffLineNumber ?? fallbackGray),
|
|
246
|
+
diffAddedLineNumberBg: resolveColorToHex(t.diffAddedLineNumberBg ?? '#1e3a1e'),
|
|
247
|
+
diffRemovedLineNumberBg: resolveColorToHex(t.diffRemovedLineNumberBg ?? '#3a1e1e'),
|
|
248
|
+
|
|
249
|
+
// Markdown
|
|
250
|
+
markdownText: resolveColorToHex(t.markdownText ?? t.text ?? fallbackText),
|
|
251
|
+
markdownHeading: resolveColorToHex(t.markdownHeading ?? t.primary ?? fallbackGray),
|
|
252
|
+
markdownLink: resolveColorToHex(t.markdownLink ?? t.primary ?? fallbackGray),
|
|
253
|
+
markdownLinkText: resolveColorToHex(t.markdownLinkText ?? t.primary ?? fallbackGray),
|
|
254
|
+
markdownCode: resolveColorToHex(t.markdownCode ?? t.primary ?? fallbackGray),
|
|
255
|
+
markdownBlockQuote: resolveColorToHex(t.markdownBlockQuote ?? fallbackGray),
|
|
256
|
+
markdownEmph: resolveColorToHex(t.markdownEmph ?? t.primary ?? fallbackGray),
|
|
257
|
+
markdownStrong: resolveColorToHex(t.markdownStrong ?? t.primary ?? fallbackGray),
|
|
258
|
+
markdownHorizontalRule: resolveColorToHex(t.markdownHorizontalRule ?? fallbackGray),
|
|
259
|
+
markdownListItem: resolveColorToHex(t.markdownListItem ?? t.primary ?? fallbackGray),
|
|
260
|
+
markdownListEnumeration: resolveColorToHex(t.markdownListEnumeration ?? t.primary ?? fallbackGray),
|
|
261
|
+
markdownImage: resolveColorToHex(t.markdownImage ?? t.primary ?? fallbackGray),
|
|
262
|
+
markdownImageText: resolveColorToHex(t.markdownImageText ?? t.primary ?? fallbackGray),
|
|
263
|
+
markdownCodeBlock: resolveColorToHex(t.markdownCodeBlock ?? t.text ?? fallbackText),
|
|
264
|
+
|
|
265
|
+
// Syntax
|
|
266
|
+
syntaxComment: resolveColorToHex(t.syntaxComment ?? fallbackGray),
|
|
267
|
+
syntaxKeyword: resolveColorToHex(t.syntaxKeyword ?? t.primary ?? fallbackGray),
|
|
268
|
+
syntaxFunction: resolveColorToHex(t.syntaxFunction ?? t.primary ?? fallbackGray),
|
|
269
|
+
syntaxVariable: resolveColorToHex(t.syntaxVariable ?? fallbackGray),
|
|
270
|
+
syntaxString: resolveColorToHex(t.syntaxString ?? t.primary ?? fallbackGray),
|
|
271
|
+
syntaxNumber: resolveColorToHex(t.syntaxNumber ?? t.primary ?? fallbackGray),
|
|
272
|
+
syntaxType: resolveColorToHex(t.syntaxType ?? t.primary ?? fallbackGray),
|
|
273
|
+
syntaxOperator: resolveColorToHex(t.syntaxOperator ?? t.primary ?? fallbackGray),
|
|
274
|
+
syntaxPunctuation: resolveColorToHex(t.syntaxPunctuation ?? t.text ?? fallbackText),
|
|
275
|
+
|
|
276
|
+
// Transparent
|
|
277
|
+
transparent: undefined,
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export function getResolvedTheme(
|
|
282
|
+
name: string,
|
|
283
|
+
mode: 'dark' | 'light' = 'dark',
|
|
284
|
+
): ResolvedTheme {
|
|
285
|
+
const themeJson = DEFAULT_THEMES[name] ?? DEFAULT_THEMES.termcast!
|
|
286
|
+
return resolveTheme(themeJson, mode)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export const themeNames = Object.keys(DEFAULT_THEMES).sort()
|
|
290
|
+
|
|
291
|
+
export const defaultThemeName = 'termcast'
|
|
@@ -97,8 +97,9 @@ export interface RunCommandOptions {
|
|
|
97
97
|
extensionName: string
|
|
98
98
|
packageJson?: RaycastPackageJson
|
|
99
99
|
bundledPath?: string
|
|
100
|
-
|
|
100
|
+
loadComponent?: () => Promise<(props: LaunchProps) => any>
|
|
101
101
|
push: (element: React.ReactNode) => void
|
|
102
|
+
replace?: (element: React.ReactNode) => void
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
export async function runCommand(options: RunCommandOptions): Promise<void> {
|
|
@@ -107,8 +108,9 @@ export async function runCommand(options: RunCommandOptions): Promise<void> {
|
|
|
107
108
|
extensionName,
|
|
108
109
|
packageJson,
|
|
109
110
|
bundledPath,
|
|
110
|
-
|
|
111
|
+
loadComponent,
|
|
111
112
|
push,
|
|
113
|
+
replace,
|
|
112
114
|
} = options
|
|
113
115
|
|
|
114
116
|
// Check if command has required preferences that are missing
|
|
@@ -116,12 +118,11 @@ export async function runCommand(options: RunCommandOptions): Promise<void> {
|
|
|
116
118
|
command,
|
|
117
119
|
extensionName,
|
|
118
120
|
packageJson,
|
|
119
|
-
hasBuiltInComponent: !!BuiltInComponent,
|
|
120
121
|
})
|
|
121
122
|
|
|
122
123
|
if (!prefsCheck.hasRequiredPreferences) {
|
|
123
|
-
// TODO: Use replace instead of push to avoid stacking navigation
|
|
124
124
|
// Redirect to preferences with onSubmit to run command after
|
|
125
|
+
// Use replace in onSubmit so the command replaces the preferences screen
|
|
125
126
|
push(
|
|
126
127
|
<ExtensionPreferences
|
|
127
128
|
extensionName={extensionName}
|
|
@@ -131,7 +132,7 @@ export async function runCommand(options: RunCommandOptions): Promise<void> {
|
|
|
131
132
|
: undefined
|
|
132
133
|
}
|
|
133
134
|
onSubmit={() => {
|
|
134
|
-
runCommand(options)
|
|
135
|
+
runCommand({ ...options, push: replace || push })
|
|
135
136
|
}}
|
|
136
137
|
/>,
|
|
137
138
|
)
|
|
@@ -144,13 +145,14 @@ export async function runCommand(options: RunCommandOptions): Promise<void> {
|
|
|
144
145
|
const needsArguments = commandArgs.length > 0 && !currentArgs
|
|
145
146
|
|
|
146
147
|
if (needsArguments) {
|
|
148
|
+
// Use replace in onSubmit so the command replaces the arguments screen
|
|
147
149
|
push(
|
|
148
150
|
<CommandArguments
|
|
149
151
|
arguments={commandArgs}
|
|
150
152
|
commandTitle={command.title}
|
|
151
153
|
onSubmit={(args) => {
|
|
152
154
|
useStore.setState({ currentCommandArguments: args })
|
|
153
|
-
runCommand(options)
|
|
155
|
+
runCommand({ ...options, push: replace || push })
|
|
154
156
|
}}
|
|
155
157
|
/>,
|
|
156
158
|
)
|
|
@@ -163,9 +165,20 @@ export async function runCommand(options: RunCommandOptions): Promise<void> {
|
|
|
163
165
|
// Get the component/function to run
|
|
164
166
|
let CommandComponent: ((props: LaunchProps) => any) | undefined
|
|
165
167
|
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
+
if (loadComponent) {
|
|
169
|
+
// Lazy load the component (used by compiled extensions and built-in commands)
|
|
170
|
+
CommandComponent = await loadComponent()
|
|
171
|
+
|
|
172
|
+
if (!CommandComponent) {
|
|
173
|
+
await showToast({
|
|
174
|
+
style: Toast.Style.Failure,
|
|
175
|
+
title: 'No default export',
|
|
176
|
+
message: `Command file ${command.name} has no default export`,
|
|
177
|
+
})
|
|
178
|
+
return
|
|
179
|
+
}
|
|
168
180
|
} else if (bundledPath) {
|
|
181
|
+
// Dynamic import with cache busting (used by dev mode)
|
|
169
182
|
const state = useStore.getState()
|
|
170
183
|
const devRebuildCount = state.devRebuildCount + 1
|
|
171
184
|
useStore.setState({ devRebuildCount })
|
|
@@ -224,18 +237,16 @@ async function checkRequiredPreferences({
|
|
|
224
237
|
command,
|
|
225
238
|
extensionName,
|
|
226
239
|
packageJson,
|
|
227
|
-
hasBuiltInComponent,
|
|
228
240
|
}: {
|
|
229
241
|
command: RunnableCommand
|
|
230
242
|
extensionName: string
|
|
231
243
|
packageJson?: RaycastPackageJson
|
|
232
|
-
hasBuiltInComponent: boolean
|
|
233
244
|
}): Promise<{
|
|
234
245
|
hasRequiredPreferences: boolean
|
|
235
246
|
requiredPreferences?: 'command' | 'extension'
|
|
236
247
|
}> {
|
|
237
|
-
//
|
|
238
|
-
if (
|
|
248
|
+
// Commands without packageJson don't have preferences
|
|
249
|
+
if (!packageJson) {
|
|
239
250
|
return { hasRequiredPreferences: true }
|
|
240
251
|
}
|
|
241
252
|
|
package/src/utils.tsx
CHANGED
|
@@ -28,9 +28,10 @@ export type CommonProps = {
|
|
|
28
28
|
|
|
29
29
|
export interface Application {
|
|
30
30
|
name: string
|
|
31
|
-
localizedName?: string
|
|
32
31
|
path: string
|
|
33
32
|
bundleId?: string
|
|
33
|
+
localizedName?: string
|
|
34
|
+
windowsAppId?: string
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export type PathLike = string | Buffer | { href: string; toString(): string }
|
|
@@ -80,41 +81,137 @@ export async function getDefaultApplication(
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
export async function getFrontmostApplication(): Promise<Application> {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
if (process.platform !== 'darwin') {
|
|
85
|
+
throw new Error('getFrontmostApplication is only supported on macOS')
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const { execSync } = await import('node:child_process')
|
|
89
|
+
|
|
90
|
+
// Get frontmost app bundle ID
|
|
91
|
+
const bundleId = execSync(
|
|
92
|
+
`osascript -e 'tell application "System Events" to get bundle identifier of first application process whose frontmost is true'`,
|
|
93
|
+
{ encoding: 'utf-8' },
|
|
94
|
+
).trim()
|
|
95
|
+
|
|
96
|
+
// Get app path from bundle ID
|
|
97
|
+
const path = execSync(
|
|
98
|
+
`mdfind "kMDItemCFBundleIdentifier == '${bundleId}'" | head -1`,
|
|
99
|
+
{ encoding: 'utf-8' },
|
|
100
|
+
).trim()
|
|
101
|
+
|
|
102
|
+
// Get app name from path
|
|
103
|
+
const name = path.split('/').pop()?.replace('.app', '') || bundleId
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
name,
|
|
107
|
+
localizedName: name,
|
|
108
|
+
path,
|
|
109
|
+
bundleId,
|
|
90
110
|
}
|
|
91
|
-
return Promise.resolve(frontmostApp)
|
|
92
111
|
}
|
|
93
112
|
|
|
94
113
|
export async function showInFinder(path: PathLike): Promise<void> {
|
|
95
|
-
// TODO: Implement system call to show file in Finder
|
|
96
114
|
const pathStr = typeof path === 'string' ? path : path.toString()
|
|
97
|
-
|
|
98
|
-
|
|
115
|
+
|
|
116
|
+
if (process.platform !== 'darwin') {
|
|
117
|
+
// On non-macOS, just open the parent directory
|
|
118
|
+
const { dirname } = await import('node:path')
|
|
119
|
+
return open(dirname(pathStr))
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const { spawn } = await import('node:child_process')
|
|
123
|
+
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
// -R reveals the file in Finder
|
|
126
|
+
const child = spawn('open', ['-R', pathStr], { stdio: 'ignore' })
|
|
127
|
+
child.on('error', reject)
|
|
128
|
+
child.on('close', (code) => {
|
|
129
|
+
if (code === 0) {
|
|
130
|
+
resolve()
|
|
131
|
+
} else {
|
|
132
|
+
reject(new Error(`showInFinder failed with code ${code}`))
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
})
|
|
99
136
|
}
|
|
100
137
|
|
|
101
138
|
export async function trash(path: PathLike | PathLike[]): Promise<void> {
|
|
102
|
-
// TODO: Implement system call to move files to trash
|
|
103
139
|
const paths = Array.isArray(path) ? path : [path]
|
|
104
140
|
const pathStrs = paths.map((p) => (typeof p === 'string' ? p : p.toString()))
|
|
105
|
-
|
|
106
|
-
|
|
141
|
+
|
|
142
|
+
if (process.platform === 'darwin') {
|
|
143
|
+
const { execSync } = await import('node:child_process')
|
|
144
|
+
|
|
145
|
+
for (const filePath of pathStrs) {
|
|
146
|
+
// Use osascript to move to trash via Finder (proper macOS trash behavior)
|
|
147
|
+
execSync(
|
|
148
|
+
`osascript -e 'tell application "Finder" to delete POSIX file "${filePath}"'`,
|
|
149
|
+
{ stdio: 'ignore' },
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
} else if (process.platform === 'win32') {
|
|
153
|
+
// Windows: use PowerShell to move to recycle bin
|
|
154
|
+
const { execSync } = await import('node:child_process')
|
|
155
|
+
|
|
156
|
+
for (const filePath of pathStrs) {
|
|
157
|
+
execSync(
|
|
158
|
+
`powershell -Command "Add-Type -AssemblyName Microsoft.VisualBasic; [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile('${filePath}', 'OnlyErrorDialogs', 'SendToRecycleBin')"`,
|
|
159
|
+
{ stdio: 'ignore' },
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
// Linux: try trash-cli, fall back to gio trash
|
|
164
|
+
const { execSync, spawnSync } = await import('node:child_process')
|
|
165
|
+
|
|
166
|
+
// Check if trash-cli is available
|
|
167
|
+
const hasTrashCli = spawnSync('which', ['trash-put']).status === 0
|
|
168
|
+
const hasGio = spawnSync('which', ['gio']).status === 0
|
|
169
|
+
|
|
170
|
+
for (const filePath of pathStrs) {
|
|
171
|
+
if (hasTrashCli) {
|
|
172
|
+
execSync(`trash-put "${filePath}"`, { stdio: 'ignore' })
|
|
173
|
+
} else if (hasGio) {
|
|
174
|
+
execSync(`gio trash "${filePath}"`, { stdio: 'ignore' })
|
|
175
|
+
} else {
|
|
176
|
+
throw new Error(
|
|
177
|
+
'No trash utility found. Install trash-cli or gio.',
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
107
182
|
}
|
|
108
183
|
|
|
109
184
|
export async function open(
|
|
110
185
|
target: string,
|
|
111
186
|
application?: Application | string,
|
|
112
187
|
): Promise<void> {
|
|
113
|
-
|
|
188
|
+
const { spawn } = await import('node:child_process')
|
|
114
189
|
const appName =
|
|
115
190
|
typeof application === 'string' ? application : application?.name
|
|
116
|
-
|
|
117
|
-
return Promise
|
|
191
|
+
|
|
192
|
+
return new Promise((resolve, reject) => {
|
|
193
|
+
let cmd: string
|
|
194
|
+
let args: string[]
|
|
195
|
+
|
|
196
|
+
if (process.platform === 'darwin') {
|
|
197
|
+
// macOS
|
|
198
|
+
cmd = 'open'
|
|
199
|
+
args = appName ? ['-a', appName, target] : [target]
|
|
200
|
+
} else if (process.platform === 'win32') {
|
|
201
|
+
// Windows
|
|
202
|
+
cmd = 'cmd'
|
|
203
|
+
args = ['/c', 'start', '', target]
|
|
204
|
+
} else {
|
|
205
|
+
// Linux and others
|
|
206
|
+
cmd = 'xdg-open'
|
|
207
|
+
args = [target]
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const child = spawn(cmd, args, { stdio: 'ignore', detached: true })
|
|
211
|
+
child.unref()
|
|
212
|
+
child.on('error', reject)
|
|
213
|
+
child.on('spawn', () => resolve())
|
|
214
|
+
})
|
|
118
215
|
}
|
|
119
216
|
|
|
120
217
|
export function captureException(exception: unknown): void {
|
package/src/watcher.tsx
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Dynamic watcher loader - only initializes when first called
|
|
2
|
+
// Following opencode's approach for bundling native modules in compiled binaries
|
|
3
|
+
// @ts-ignore - wrapper.js exists but types don't export it
|
|
4
|
+
import { createWrapper } from '@parcel/watcher/wrapper'
|
|
5
|
+
import type ParcelWatcher from '@parcel/watcher'
|
|
6
|
+
|
|
7
|
+
let _watcher: typeof ParcelWatcher | undefined
|
|
8
|
+
|
|
9
|
+
export function getWatcher(): typeof ParcelWatcher {
|
|
10
|
+
if (_watcher) return _watcher
|
|
11
|
+
// Use require with template literal so Bun can analyze and bundle the native module
|
|
12
|
+
// Linux requires -glibc suffix for the native binding
|
|
13
|
+
const suffix = process.platform === 'linux' ? '-glibc' : ''
|
|
14
|
+
const binding = require(
|
|
15
|
+
`@parcel/watcher-${process.platform}-${process.arch}${suffix}`,
|
|
16
|
+
)
|
|
17
|
+
_watcher = createWrapper(binding)
|
|
18
|
+
return _watcher!
|
|
19
|
+
}
|