@pablozaiden/terminatui 0.2.0 → 0.3.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.
- package/README.md +64 -43
- package/package.json +11 -8
- package/src/__tests__/application.test.ts +87 -68
- package/src/__tests__/buildCliCommand.test.ts +99 -119
- package/src/__tests__/builtins.test.ts +27 -75
- package/src/__tests__/command.test.ts +100 -131
- package/src/__tests__/configOnChange.test.ts +63 -0
- package/src/__tests__/context.test.ts +1 -26
- package/src/__tests__/helpCore.test.ts +227 -0
- package/src/__tests__/parser.test.ts +98 -244
- package/src/__tests__/registry.test.ts +33 -160
- package/src/__tests__/schemaToFields.test.ts +75 -158
- package/src/builtins/help.ts +12 -4
- package/src/builtins/settings.ts +18 -32
- package/src/builtins/version.ts +3 -3
- package/src/cli/output/colors.ts +1 -1
- package/src/cli/parser.ts +26 -95
- package/src/core/application.ts +192 -110
- package/src/core/command.ts +26 -9
- package/src/core/context.ts +31 -20
- package/src/core/help.ts +24 -18
- package/src/core/knownCommands.ts +13 -0
- package/src/core/logger.ts +39 -42
- package/src/core/registry.ts +5 -12
- package/src/index.ts +22 -137
- package/src/tui/TuiApplication.tsx +63 -120
- package/src/tui/TuiRoot.tsx +135 -0
- package/src/tui/adapters/factory.ts +19 -0
- package/src/tui/adapters/ink/InkRenderer.tsx +139 -0
- package/src/tui/adapters/ink/components/Button.tsx +12 -0
- package/src/tui/adapters/ink/components/Code.tsx +6 -0
- package/src/tui/adapters/ink/components/CodeHighlight.tsx +6 -0
- package/src/tui/adapters/ink/components/Container.tsx +5 -0
- package/src/tui/adapters/ink/components/Field.tsx +12 -0
- package/src/tui/adapters/ink/components/Label.tsx +24 -0
- package/src/tui/adapters/ink/components/MenuButton.tsx +12 -0
- package/src/tui/adapters/ink/components/MenuItem.tsx +17 -0
- package/src/tui/adapters/ink/components/Overlay.tsx +5 -0
- package/src/tui/adapters/ink/components/Panel.tsx +15 -0
- package/src/tui/adapters/ink/components/ScrollView.tsx +5 -0
- package/src/tui/adapters/ink/components/Select.tsx +44 -0
- package/src/tui/adapters/ink/components/Spacer.tsx +15 -0
- package/src/tui/adapters/ink/components/Spinner.tsx +5 -0
- package/src/tui/adapters/ink/components/TextInput.tsx +22 -0
- package/src/tui/adapters/ink/components/Value.tsx +7 -0
- package/src/tui/adapters/ink/keyboard.ts +97 -0
- package/src/tui/adapters/ink/utils.ts +16 -0
- package/src/tui/adapters/opentui/OpenTuiRenderer.tsx +119 -0
- package/src/tui/adapters/opentui/components/Button.tsx +13 -0
- package/src/tui/adapters/opentui/components/Code.tsx +12 -0
- package/src/tui/adapters/opentui/components/CodeHighlight.tsx +24 -0
- package/src/tui/adapters/opentui/components/Container.tsx +56 -0
- package/src/tui/adapters/opentui/components/Field.tsx +18 -0
- package/src/tui/adapters/opentui/components/Label.tsx +15 -0
- package/src/tui/adapters/opentui/components/MenuButton.tsx +14 -0
- package/src/tui/adapters/opentui/components/MenuItem.tsx +29 -0
- package/src/tui/adapters/opentui/components/Overlay.tsx +21 -0
- package/src/tui/adapters/opentui/components/Panel.tsx +78 -0
- package/src/tui/adapters/opentui/components/ScrollView.tsx +85 -0
- package/src/tui/adapters/opentui/components/Select.tsx +59 -0
- package/src/tui/adapters/opentui/components/Spacer.tsx +5 -0
- package/src/tui/adapters/opentui/components/Spinner.tsx +12 -0
- package/src/tui/adapters/opentui/components/TextInput.tsx +13 -0
- package/src/tui/adapters/opentui/components/Value.tsx +13 -0
- package/src/tui/{hooks → adapters/opentui/hooks}/useSpinner.ts +2 -11
- package/src/tui/adapters/opentui/keyboard.ts +61 -0
- package/src/tui/adapters/types.ts +71 -0
- package/src/tui/components/ActionButton.tsx +0 -36
- package/src/tui/components/CommandSelector.tsx +45 -92
- package/src/tui/components/ConfigForm.tsx +68 -42
- package/src/tui/components/FieldRow.tsx +0 -30
- package/src/tui/components/Header.tsx +14 -13
- package/src/tui/components/JsonHighlight.tsx +10 -17
- package/src/tui/components/ModalBase.tsx +38 -0
- package/src/tui/components/ResultsPanel.tsx +27 -36
- package/src/tui/components/StatusBar.tsx +24 -39
- package/src/tui/components/logColors.ts +12 -0
- package/src/tui/context/ClipboardContext.tsx +87 -0
- package/src/tui/context/ExecutorContext.tsx +139 -0
- package/src/tui/context/KeyboardContext.tsx +85 -71
- package/src/tui/context/LogsContext.tsx +35 -0
- package/src/tui/context/NavigationContext.tsx +194 -0
- package/src/tui/context/RendererContext.tsx +20 -0
- package/src/tui/context/TuiAppContext.tsx +58 -0
- package/src/tui/hooks/useActiveKeyHandler.ts +75 -0
- package/src/tui/hooks/useBackHandler.ts +34 -0
- package/src/tui/hooks/useClipboard.ts +40 -25
- package/src/tui/hooks/useClipboardProvider.ts +42 -0
- package/src/tui/hooks/useGlobalKeyHandler.ts +54 -0
- package/src/tui/modals/CliModal.tsx +82 -0
- package/src/tui/modals/EditorModal.tsx +207 -0
- package/src/tui/modals/LogsModal.tsx +98 -0
- package/src/tui/registry.ts +102 -0
- package/src/tui/screens/CommandSelectScreen.tsx +162 -0
- package/src/tui/screens/ConfigScreen.tsx +165 -0
- package/src/tui/screens/ErrorScreen.tsx +58 -0
- package/src/tui/screens/ResultsScreen.tsx +68 -0
- package/src/tui/screens/RunningScreen.tsx +72 -0
- package/src/tui/screens/ScreenBase.ts +6 -0
- package/src/tui/semantic/Button.tsx +7 -0
- package/src/tui/semantic/Code.tsx +7 -0
- package/src/tui/semantic/CodeHighlight.tsx +7 -0
- package/src/tui/semantic/Container.tsx +7 -0
- package/src/tui/semantic/Field.tsx +7 -0
- package/src/tui/semantic/Label.tsx +7 -0
- package/src/tui/semantic/MenuButton.tsx +7 -0
- package/src/tui/semantic/MenuItem.tsx +7 -0
- package/src/tui/semantic/Overlay.tsx +7 -0
- package/src/tui/semantic/Panel.tsx +7 -0
- package/src/tui/semantic/ScrollView.tsx +9 -0
- package/src/tui/semantic/Select.tsx +7 -0
- package/src/tui/semantic/Spacer.tsx +7 -0
- package/src/tui/semantic/Spinner.tsx +7 -0
- package/src/tui/semantic/TextInput.tsx +7 -0
- package/src/tui/semantic/Value.tsx +7 -0
- package/src/tui/semantic/types.ts +195 -0
- package/src/tui/theme.ts +25 -14
- package/src/tui/utils/buildCliCommand.ts +1 -0
- package/src/tui/utils/getEnumKeys.ts +3 -0
- package/src/tui/utils/parameterPersistence.ts +1 -0
- package/src/types/command.ts +0 -60
- package/.devcontainer/devcontainer.json +0 -19
- package/.devcontainer/install-prerequisites.sh +0 -49
- package/.github/workflows/copilot-setup-steps.yml +0 -32
- package/.github/workflows/pull-request.yml +0 -27
- package/.github/workflows/release-npm-package.yml +0 -81
- package/AGENTS.md +0 -31
- package/bun.lock +0 -236
- package/examples/tui-app/commands/config/app/get.ts +0 -66
- package/examples/tui-app/commands/config/app/index.ts +0 -27
- package/examples/tui-app/commands/config/app/set.ts +0 -86
- package/examples/tui-app/commands/config/index.ts +0 -32
- package/examples/tui-app/commands/config/user/get.ts +0 -65
- package/examples/tui-app/commands/config/user/index.ts +0 -27
- package/examples/tui-app/commands/config/user/set.ts +0 -61
- package/examples/tui-app/commands/greet.ts +0 -76
- package/examples/tui-app/commands/index.ts +0 -4
- package/examples/tui-app/commands/math.ts +0 -115
- package/examples/tui-app/commands/status.ts +0 -77
- package/examples/tui-app/index.ts +0 -35
- package/guides/01-hello-world.md +0 -96
- package/guides/02-adding-options.md +0 -103
- package/guides/03-multiple-commands.md +0 -163
- package/guides/04-subcommands.md +0 -206
- package/guides/05-interactive-tui.md +0 -194
- package/guides/06-config-validation.md +0 -264
- package/guides/07-async-cancellation.md +0 -336
- package/guides/08-complete-application.md +0 -537
- package/guides/README.md +0 -74
- package/src/__tests__/colors.test.ts +0 -127
- package/src/__tests__/commandClass.test.ts +0 -130
- package/src/__tests__/help.test.ts +0 -412
- package/src/__tests__/registryNew.test.ts +0 -160
- package/src/__tests__/table.test.ts +0 -146
- package/src/__tests__/tui.test.ts +0 -26
- package/src/builtins/index.ts +0 -4
- package/src/cli/help.ts +0 -174
- package/src/cli/index.ts +0 -3
- package/src/cli/output/index.ts +0 -2
- package/src/cli/output/table.ts +0 -141
- package/src/commands/help.ts +0 -50
- package/src/commands/index.ts +0 -1
- package/src/components/index.ts +0 -147
- package/src/core/index.ts +0 -15
- package/src/hooks/index.ts +0 -131
- package/src/registry/commandRegistry.ts +0 -77
- package/src/registry/index.ts +0 -1
- package/src/tui/TuiApp.tsx +0 -619
- package/src/tui/app.ts +0 -29
- package/src/tui/components/CliModal.tsx +0 -81
- package/src/tui/components/EditorModal.tsx +0 -177
- package/src/tui/components/LogsPanel.tsx +0 -86
- package/src/tui/components/index.ts +0 -13
- package/src/tui/context/index.ts +0 -7
- package/src/tui/hooks/index.ts +0 -35
- package/src/tui/hooks/useKeyboardHandler.ts +0 -91
- package/src/tui/hooks/useLogStream.ts +0 -96
- package/src/tui/index.ts +0 -65
- package/src/tui/utils/index.ts +0 -13
- package/src/types/index.ts +0 -1
- package/tsconfig.json +0 -25
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ScrollViewProps, ScrollViewRef } from "./types.ts";
|
|
2
|
+
import { useRenderer } from "../context/RendererContext.tsx";
|
|
3
|
+
|
|
4
|
+
export function ScrollView(props: ScrollViewProps) {
|
|
5
|
+
const renderer = useRenderer();
|
|
6
|
+
return renderer.components.ScrollView(props);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type { ScrollViewRef };
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export type Align = "flex-start" | "center" | "flex-end" | "stretch";
|
|
4
|
+
export type Justify = "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | "space-evenly";
|
|
5
|
+
export type FlexDirection = "row" | "column";
|
|
6
|
+
|
|
7
|
+
export interface Spacing {
|
|
8
|
+
top?: number;
|
|
9
|
+
right?: number;
|
|
10
|
+
bottom?: number;
|
|
11
|
+
left?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ThemeConfig {
|
|
15
|
+
colors: {
|
|
16
|
+
background: string;
|
|
17
|
+
panelBackground: string;
|
|
18
|
+
overlay: string;
|
|
19
|
+
|
|
20
|
+
text: string;
|
|
21
|
+
mutedText: string;
|
|
22
|
+
inverseText: string;
|
|
23
|
+
|
|
24
|
+
border: string;
|
|
25
|
+
focusBorder: string;
|
|
26
|
+
|
|
27
|
+
primary: string;
|
|
28
|
+
primaryText: string;
|
|
29
|
+
|
|
30
|
+
success: string;
|
|
31
|
+
warning: string;
|
|
32
|
+
error: string;
|
|
33
|
+
|
|
34
|
+
value: string;
|
|
35
|
+
code: string;
|
|
36
|
+
|
|
37
|
+
selectionBackground: string;
|
|
38
|
+
selectionText: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type SemanticColor = keyof ThemeConfig["colors"];
|
|
43
|
+
|
|
44
|
+
export interface LayoutProps {
|
|
45
|
+
flex?: number;
|
|
46
|
+
width?: number | string;
|
|
47
|
+
height?: number | string;
|
|
48
|
+
|
|
49
|
+
flexDirection?: FlexDirection;
|
|
50
|
+
alignItems?: Align;
|
|
51
|
+
justifyContent?: Justify;
|
|
52
|
+
|
|
53
|
+
gap?: number;
|
|
54
|
+
padding?: number | Spacing;
|
|
55
|
+
|
|
56
|
+
/** When set, should prevent the node from shrinking in flex layouts. */
|
|
57
|
+
noShrink?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type PanelSurface = "panel" | "overlay";
|
|
61
|
+
|
|
62
|
+
export interface PanelProps extends LayoutProps {
|
|
63
|
+
title?: string;
|
|
64
|
+
focused?: boolean;
|
|
65
|
+
border?: boolean;
|
|
66
|
+
surface?: PanelSurface;
|
|
67
|
+
|
|
68
|
+
/** Renderer-level compact styling (e.g. no default padding). */
|
|
69
|
+
dense?: boolean;
|
|
70
|
+
|
|
71
|
+
children?: ReactNode;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface ContainerProps extends LayoutProps {
|
|
75
|
+
children?: ReactNode;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface ScrollViewRef {
|
|
79
|
+
scrollToTop: () => void;
|
|
80
|
+
scrollToBottom: () => void;
|
|
81
|
+
scrollToIndex: (index: number) => void;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ScrollViewProps extends LayoutProps {
|
|
85
|
+
axis?: "vertical" | "horizontal" | "both";
|
|
86
|
+
stickyToEnd?: boolean;
|
|
87
|
+
focused?: boolean;
|
|
88
|
+
scrollRef?: (ref: ScrollViewRef | null) => void;
|
|
89
|
+
children?: ReactNode;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface OverlayProps {
|
|
93
|
+
zIndex?: number;
|
|
94
|
+
top?: number | string;
|
|
95
|
+
left?: number | string;
|
|
96
|
+
right?: number | string;
|
|
97
|
+
bottom?: number | string;
|
|
98
|
+
width?: number | string;
|
|
99
|
+
height?: number | string;
|
|
100
|
+
children?: ReactNode;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface SpacerProps {
|
|
104
|
+
size: number;
|
|
105
|
+
axis?: "horizontal" | "vertical";
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface SpinnerProps {
|
|
109
|
+
active: boolean;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface LabelProps {
|
|
113
|
+
color?: SemanticColor;
|
|
114
|
+
bold?: boolean;
|
|
115
|
+
italic?: boolean;
|
|
116
|
+
wrap?: boolean;
|
|
117
|
+
children: ReactNode;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface ValueProps {
|
|
121
|
+
color?: SemanticColor;
|
|
122
|
+
truncate?: boolean;
|
|
123
|
+
children: ReactNode;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface CodeProps {
|
|
127
|
+
color?: SemanticColor;
|
|
128
|
+
children: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export type CodeTokenType =
|
|
132
|
+
| "punctuation"
|
|
133
|
+
| "string"
|
|
134
|
+
| "number"
|
|
135
|
+
| "boolean"
|
|
136
|
+
| "null"
|
|
137
|
+
| "key"
|
|
138
|
+
| "unknown";
|
|
139
|
+
|
|
140
|
+
export interface CodeToken {
|
|
141
|
+
type: CodeTokenType;
|
|
142
|
+
value: string;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface CodeHighlightProps {
|
|
146
|
+
tokens: CodeToken[];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface FieldProps {
|
|
150
|
+
label: string;
|
|
151
|
+
value: ReactNode;
|
|
152
|
+
selected?: boolean;
|
|
153
|
+
onActivate?: () => void;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface TextInputProps {
|
|
157
|
+
value: string;
|
|
158
|
+
placeholder?: string;
|
|
159
|
+
focused?: boolean;
|
|
160
|
+
onChange: (value: string) => void;
|
|
161
|
+
onSubmit?: () => void;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface SelectOption {
|
|
165
|
+
label: string;
|
|
166
|
+
value: string;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface SelectProps {
|
|
170
|
+
options: SelectOption[];
|
|
171
|
+
value: string;
|
|
172
|
+
focused?: boolean;
|
|
173
|
+
onChange: (value: string) => void;
|
|
174
|
+
onSubmit?: () => void;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface ButtonProps {
|
|
178
|
+
label: string;
|
|
179
|
+
selected?: boolean;
|
|
180
|
+
onActivate?: () => void;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface MenuButtonProps {
|
|
184
|
+
label: string;
|
|
185
|
+
selected?: boolean;
|
|
186
|
+
onActivate?: () => void;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface MenuItemProps {
|
|
190
|
+
label: string;
|
|
191
|
+
description?: string;
|
|
192
|
+
suffix?: string;
|
|
193
|
+
selected?: boolean;
|
|
194
|
+
onActivate?: () => void;
|
|
195
|
+
}
|
package/src/tui/theme.ts
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default TUI theme
|
|
2
|
+
* Default TUI theme.
|
|
3
|
+
*
|
|
4
|
+
* This is intentionally semantic: UI code should reference meanings
|
|
5
|
+
* (e.g. "error", "mutedText", "selectionBackground") rather than hardcoding colors.
|
|
3
6
|
*/
|
|
4
|
-
export const
|
|
5
|
-
background: "#
|
|
7
|
+
export const SemanticColors = {
|
|
8
|
+
background: "#0f1117",
|
|
9
|
+
panelBackground: "#0f1117",
|
|
10
|
+
overlay: "#101218",
|
|
11
|
+
|
|
12
|
+
text: "#d6dde6",
|
|
13
|
+
mutedText: "#666666",
|
|
14
|
+
inverseText: "#0b0c10",
|
|
15
|
+
|
|
6
16
|
border: "#2c2f36",
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
header: "#a8b3c1",
|
|
13
|
-
statusText: "#d6dde6",
|
|
14
|
-
overlay: "#0e1117",
|
|
15
|
-
overlayTitle: "#e5c07b",
|
|
16
|
-
error: "#f78888",
|
|
17
|
+
focusBorder: "#5da9e9",
|
|
18
|
+
|
|
19
|
+
primary: "#61afef",
|
|
20
|
+
primaryText: "#0b0c10",
|
|
21
|
+
|
|
17
22
|
success: "#98c379",
|
|
18
23
|
warning: "#f5c542",
|
|
24
|
+
error: "#f78888",
|
|
25
|
+
|
|
26
|
+
value: "#98c379",
|
|
27
|
+
code: "#c0cad6",
|
|
28
|
+
|
|
29
|
+
selectionBackground: "#61afef",
|
|
30
|
+
selectionText: "#0b0c10",
|
|
19
31
|
} as const;
|
|
20
32
|
|
|
21
|
-
export type ThemeColors = typeof Theme;
|
package/src/types/command.ts
CHANGED
|
@@ -41,63 +41,3 @@ export type OptionValues<T extends OptionSchema> = {
|
|
|
41
41
|
: unknown;
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
/**
|
|
45
|
-
* Context passed to command executors
|
|
46
|
-
*/
|
|
47
|
-
export interface CommandContext<T extends OptionSchema = OptionSchema> {
|
|
48
|
-
options: OptionValues<T>;
|
|
49
|
-
args: string[];
|
|
50
|
-
commandPath: string[];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Command executor function
|
|
55
|
-
*/
|
|
56
|
-
export type CommandExecutor<T extends OptionSchema = OptionSchema> = (
|
|
57
|
-
ctx: CommandContext<T>
|
|
58
|
-
) => void | Promise<void>;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Command definition
|
|
62
|
-
*/
|
|
63
|
-
export interface Command<
|
|
64
|
-
T extends OptionSchema = OptionSchema,
|
|
65
|
-
R = void,
|
|
66
|
-
> {
|
|
67
|
-
name: string;
|
|
68
|
-
description: string;
|
|
69
|
-
aliases?: string[];
|
|
70
|
-
hidden?: boolean;
|
|
71
|
-
options?: T;
|
|
72
|
-
subcommands?: Record<string, Command>;
|
|
73
|
-
examples?: Array<{ command: string; description: string }>;
|
|
74
|
-
execute: (ctx: CommandContext<T>) => R | Promise<R>;
|
|
75
|
-
beforeExecute?: (ctx: CommandContext<T>) => void | Promise<void>;
|
|
76
|
-
afterExecute?: (ctx: CommandContext<T>) => void | Promise<void>;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* TUI command with a render function
|
|
81
|
-
*/
|
|
82
|
-
export interface TuiCommand<T extends OptionSchema = OptionSchema>
|
|
83
|
-
extends Omit<Command<T>, "execute"> {
|
|
84
|
-
render: (ctx: CommandContext<T>) => React.ReactNode;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Define a CLI command
|
|
89
|
-
*/
|
|
90
|
-
export function defineCommand<T extends OptionSchema = OptionSchema>(
|
|
91
|
-
config: Command<T>
|
|
92
|
-
): Command<T> {
|
|
93
|
-
return config;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Define a TUI command
|
|
98
|
-
*/
|
|
99
|
-
export function defineTuiCommand<T extends OptionSchema = OptionSchema>(
|
|
100
|
-
config: TuiCommand<T>
|
|
101
|
-
): TuiCommand<T> {
|
|
102
|
-
return config;
|
|
103
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Ubuntu",
|
|
3
|
-
"image": "mcr.microsoft.com/devcontainers/base:noble",
|
|
4
|
-
"features": {
|
|
5
|
-
"ghcr.io/devcontainers/features/github-cli:1": {},
|
|
6
|
-
"ghcr.io/devcontainers/features/azure-cli:latest": {},
|
|
7
|
-
"ghcr.io/devcontainers/features/docker-outside-of-docker": {}
|
|
8
|
-
},
|
|
9
|
-
"postCreateCommand": "./.devcontainer/install-prerequisites.sh",
|
|
10
|
-
"customizations": {
|
|
11
|
-
"vscode": {
|
|
12
|
-
"extensions": [
|
|
13
|
-
"oven.bun-vscode",
|
|
14
|
-
"ms-azuretools.vscode-docker",
|
|
15
|
-
"SanjulaGanepola.github-local-actions"
|
|
16
|
-
]
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
set -e
|
|
4
|
-
|
|
5
|
-
# if bun is not installed, install it
|
|
6
|
-
if ! command -v bun &> /dev/null
|
|
7
|
-
then
|
|
8
|
-
echo "Bun not found, installing..."
|
|
9
|
-
|
|
10
|
-
curl -fsSL https://bun.com/install | bash
|
|
11
|
-
|
|
12
|
-
# manual fix for missing package.json issue
|
|
13
|
-
if [ ! -f "$HOME/.bun/install/global/package.json" ]; then
|
|
14
|
-
echo "Creating missing package.json for bun global..."
|
|
15
|
-
mkdir -p "$HOME/.bun/install/global"
|
|
16
|
-
echo '{}' > "$HOME/.bun/install/global/package.json"
|
|
17
|
-
fi
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# add bun to PATH
|
|
21
|
-
export PATH="$HOME/.bun/bin:$PATH"
|
|
22
|
-
fi
|
|
23
|
-
|
|
24
|
-
# if there is no symlink for node, create it
|
|
25
|
-
if ! command -v node &> /dev/null
|
|
26
|
-
then
|
|
27
|
-
# discover the bun binary location
|
|
28
|
-
bunBinary=$(which bun)
|
|
29
|
-
echo "Bun binary located at: $bunBinary"
|
|
30
|
-
echo "Creating symlink for node to bun..."
|
|
31
|
-
mkdir -p $HOME/.local/bin
|
|
32
|
-
ln -sf "$bunBinary" "$HOME/.local/bin/node"
|
|
33
|
-
fi
|
|
34
|
-
|
|
35
|
-
export BUN_INSTALL_BIN=$HOME/.bun/bin
|
|
36
|
-
export BUN_INSTALL_GLOBAL_DIR=$HOME/.bun/global
|
|
37
|
-
|
|
38
|
-
# Ensure dirs exist and are owned by the current user
|
|
39
|
-
mkdir -p "$BUN_INSTALL_BIN" "$BUN_INSTALL_GLOBAL_DIR"
|
|
40
|
-
export PATH="$HOME/.bun/bin:$HOME/.bun/global/bin:${PATH}"
|
|
41
|
-
|
|
42
|
-
# add the paths to bashrc and zshrc
|
|
43
|
-
echo 'export PATH="$HOME/.bun/bin:$HOME/.bun/global/bin:${PATH}" ' >> $HOME/.bashrc
|
|
44
|
-
echo 'export PATH="$HOME/.bun/bin:$HOME/.bun/global/bin:${PATH}" '>> $HOME/.zshrc
|
|
45
|
-
|
|
46
|
-
# ensure $HOME/.local/bin is in PATH for current session and future shells
|
|
47
|
-
export PATH="$HOME/.local/bin:$PATH"
|
|
48
|
-
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc"
|
|
49
|
-
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.zshrc"
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
name: "Copilot Setup Steps"
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_dispatch:
|
|
5
|
-
push:
|
|
6
|
-
paths:
|
|
7
|
-
- .github/workflows/copilot-setup-steps.yml
|
|
8
|
-
pull_request:
|
|
9
|
-
paths:
|
|
10
|
-
- .github/workflows/copilot-setup-steps.yml
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
|
|
14
|
-
copilot-setup-steps:
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
|
|
17
|
-
permissions:
|
|
18
|
-
contents: read
|
|
19
|
-
|
|
20
|
-
steps:
|
|
21
|
-
- name: Checkout repository
|
|
22
|
-
uses: actions/checkout@v6
|
|
23
|
-
|
|
24
|
-
- name: Install prerequisites
|
|
25
|
-
run: |
|
|
26
|
-
chmod +x ./.devcontainer/install-prerequisites.sh
|
|
27
|
-
./.devcontainer/install-prerequisites.sh
|
|
28
|
-
echo "$HOME/.bun/bin" >> $GITHUB_PATH
|
|
29
|
-
echo "$HOME/.bun/global/bin" >> $GITHUB_PATH
|
|
30
|
-
|
|
31
|
-
- name: Install dependencies
|
|
32
|
-
run: bun install
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
name: Pull Request
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
branches: [ "main" ]
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
test:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
environment: PR
|
|
11
|
-
|
|
12
|
-
steps:
|
|
13
|
-
- name: Checkout repository
|
|
14
|
-
uses: actions/checkout@v6
|
|
15
|
-
|
|
16
|
-
- name: Install prerequisites
|
|
17
|
-
run: |
|
|
18
|
-
chmod +x .devcontainer/install-prerequisites.sh
|
|
19
|
-
./.devcontainer/install-prerequisites.sh
|
|
20
|
-
echo "$HOME/.bun/bin" >> $GITHUB_PATH
|
|
21
|
-
echo "$HOME/.bun/global/bin" >> $GITHUB_PATH
|
|
22
|
-
|
|
23
|
-
- name: Install dependencies
|
|
24
|
-
run: bun install
|
|
25
|
-
|
|
26
|
-
- name: Run tests
|
|
27
|
-
run: bun test
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
name: Release NPM Package
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
release:
|
|
5
|
-
types: [published]
|
|
6
|
-
workflow_dispatch:
|
|
7
|
-
inputs:
|
|
8
|
-
tag:
|
|
9
|
-
description: 'Release tag (e.g., v1.2.3)'
|
|
10
|
-
required: true
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
publish:
|
|
14
|
-
name: Publish Package
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
permissions:
|
|
17
|
-
contents: read
|
|
18
|
-
id-token: write
|
|
19
|
-
steps:
|
|
20
|
-
- name: Determine release tag
|
|
21
|
-
id: get_tag
|
|
22
|
-
run: |
|
|
23
|
-
echo "Event name: ${{ github.event_name }}"
|
|
24
|
-
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
25
|
-
TAG="${{ github.event.inputs.tag }}"
|
|
26
|
-
else
|
|
27
|
-
TAG="${{ github.event.release.tag_name }}"
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
# if the tag is empty, exit with error
|
|
31
|
-
if [ -z "$TAG" ]; then
|
|
32
|
-
echo "Error: Tag is empty"
|
|
33
|
-
exit 1
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
# Strip 'v' prefix if present
|
|
37
|
-
VERSION="${TAG#v}"
|
|
38
|
-
|
|
39
|
-
echo "Using tag: $TAG"
|
|
40
|
-
echo "Using version: $VERSION"
|
|
41
|
-
|
|
42
|
-
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
|
43
|
-
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
44
|
-
|
|
45
|
-
- name: Checkout repository
|
|
46
|
-
uses: actions/checkout@v6
|
|
47
|
-
with:
|
|
48
|
-
ref: ${{ steps.get_tag.outputs.tag }}
|
|
49
|
-
|
|
50
|
-
- name: Install bun
|
|
51
|
-
run: |
|
|
52
|
-
curl -fsSL https://bun.com/install | bash
|
|
53
|
-
echo "$HOME/.bun/bin" >> $GITHUB_PATH
|
|
54
|
-
|
|
55
|
-
- uses: actions/setup-node@v4
|
|
56
|
-
with:
|
|
57
|
-
node-version: '24'
|
|
58
|
-
registry-url: 'https://registry.npmjs.org'
|
|
59
|
-
|
|
60
|
-
- name: Set package version
|
|
61
|
-
run: |
|
|
62
|
-
VERSION="${{ steps.get_tag.outputs.version }}"
|
|
63
|
-
jq --arg version "$VERSION" '.version = $version' package.json > package.json.tmp && mv package.json.tmp package.json
|
|
64
|
-
|
|
65
|
-
- name: Verify package version
|
|
66
|
-
run: |
|
|
67
|
-
EXPECTED_VERSION="${{ steps.get_tag.outputs.version }}"
|
|
68
|
-
ACTUAL_VERSION=$(jq -r '.version' package.json)
|
|
69
|
-
if [ "$EXPECTED_VERSION" != "$ACTUAL_VERSION" ]; then
|
|
70
|
-
echo "Error: Version mismatch. Expected $EXPECTED_VERSION, got $ACTUAL_VERSION"
|
|
71
|
-
exit 1
|
|
72
|
-
fi
|
|
73
|
-
echo "Version verified: $ACTUAL_VERSION"
|
|
74
|
-
|
|
75
|
-
- name: Install dependencies
|
|
76
|
-
run: bun install
|
|
77
|
-
- name: Build package
|
|
78
|
-
run: bun run build
|
|
79
|
-
|
|
80
|
-
- name: Publish Package
|
|
81
|
-
run: npm publish --no-build
|
package/AGENTS.md
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
Default to using Bun instead of Node.js.
|
|
2
|
-
|
|
3
|
-
- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
|
|
4
|
-
- Use `bun test` instead of `jest` or `vitest`
|
|
5
|
-
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
|
|
6
|
-
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
|
|
7
|
-
- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
|
|
8
|
-
- Use `bunx <package> <command>` instead of `npx <package> <command>`
|
|
9
|
-
- Bun automatically loads .env, so don't use dotenv.
|
|
10
|
-
|
|
11
|
-
## APIs
|
|
12
|
-
|
|
13
|
-
- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
|
|
14
|
-
- Bun.$`ls` instead of execa.
|
|
15
|
-
|
|
16
|
-
## Testing
|
|
17
|
-
|
|
18
|
-
Always run `bun run build` before running tests, to make sure there are no build errors.
|
|
19
|
-
Use `bun run test` to run all the tests.
|
|
20
|
-
|
|
21
|
-
Always run `bun run test` when you think you are done making changes.
|
|
22
|
-
|
|
23
|
-
```ts#index.test.ts
|
|
24
|
-
import { test, expect } from "bun:test";
|
|
25
|
-
|
|
26
|
-
test("hello world", () => {
|
|
27
|
-
expect(1).toBe(1);
|
|
28
|
-
});
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
For more information, read the Bun API docs in `node_modules/bun-types/docs/**.mdx`.
|