@pablozaiden/terminatui 0.3.0-beta-1 → 0.4.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 (142) hide show
  1. package/package.json +10 -3
  2. package/src/__tests__/adapterNoSharedUi.test.ts +34 -0
  3. package/src/__tests__/configOnChange.test.ts +63 -0
  4. package/src/__tests__/schemaToFields.test.ts +0 -4
  5. package/src/__tests__/tuiRootNoCoupling.test.ts +25 -0
  6. package/src/builtins/version.ts +1 -1
  7. package/src/index.ts +22 -0
  8. package/src/tui/TuiApplication.tsx +0 -4
  9. package/src/tui/TuiRoot.tsx +58 -102
  10. package/src/tui/actions.ts +4 -0
  11. package/src/tui/adapters/ink/InkRenderer.tsx +191 -41
  12. package/src/tui/adapters/ink/SemanticInkRenderer.tsx +210 -0
  13. package/src/tui/adapters/ink/components/Button.tsx +10 -2
  14. package/src/tui/adapters/ink/components/Overlay.tsx +8 -2
  15. package/src/tui/adapters/ink/components/Panel.tsx +26 -5
  16. package/src/tui/adapters/ink/components/ScrollView.tsx +44 -3
  17. package/src/tui/adapters/ink/components/Spinner.tsx +8 -2
  18. package/src/tui/adapters/ink/keyboard.ts +0 -3
  19. package/src/tui/adapters/ink/ui/CommandSelector.tsx +56 -0
  20. package/src/tui/adapters/ink/ui/ConfigForm.tsx +77 -0
  21. package/src/tui/adapters/ink/ui/Header.tsx +25 -0
  22. package/src/tui/adapters/ink/ui/JsonHighlight.tsx +21 -0
  23. package/src/tui/adapters/ink/ui/ResultsPanel.tsx +57 -0
  24. package/src/tui/adapters/opentui/OpenTuiRenderer.tsx +190 -39
  25. package/src/tui/adapters/opentui/SemanticOpenTuiRenderer.tsx +192 -0
  26. package/src/tui/adapters/opentui/components/Label.tsx +2 -2
  27. package/src/tui/adapters/opentui/components/Overlay.tsx +12 -3
  28. package/src/tui/adapters/opentui/components/Panel.tsx +11 -1
  29. package/src/tui/adapters/opentui/components/ScrollView.tsx +1 -8
  30. package/src/tui/adapters/opentui/components/Spinner.tsx +1 -1
  31. package/src/tui/adapters/opentui/keyboard.ts +0 -3
  32. package/src/tui/adapters/opentui/ui/CommandSelector.tsx +55 -0
  33. package/src/tui/adapters/opentui/ui/ConfigForm.tsx +74 -0
  34. package/src/tui/adapters/opentui/ui/Header.tsx +24 -0
  35. package/src/tui/adapters/opentui/ui/JsonHighlight.tsx +20 -0
  36. package/src/tui/adapters/opentui/ui/LogsPanel.tsx +44 -0
  37. package/src/tui/adapters/opentui/ui/ResultsPanel.tsx +62 -0
  38. package/src/tui/adapters/shared/TerminalClipboard.ts +65 -0
  39. package/src/tui/adapters/{opentui/hooks → shared}/useSpinner.ts +5 -1
  40. package/src/tui/adapters/types.ts +25 -45
  41. package/src/tui/components/JsonHighlight.tsx +41 -111
  42. package/src/tui/context/ActionContext.tsx +51 -0
  43. package/src/tui/context/ExecutorContext.tsx +7 -1
  44. package/src/tui/context/NavigationContext.tsx +20 -4
  45. package/src/tui/controllers/CommandBrowserController.tsx +100 -0
  46. package/src/tui/controllers/ConfigController.tsx +183 -0
  47. package/src/tui/controllers/EditorController.tsx +169 -0
  48. package/src/tui/controllers/LogsController.tsx +48 -0
  49. package/src/tui/controllers/OutcomeController.tsx +110 -0
  50. package/src/tui/driver/TuiDriver.tsx +148 -0
  51. package/src/tui/driver/context/TuiDriverContext.tsx +44 -0
  52. package/src/tui/driver/types.ts +72 -0
  53. package/src/tui/semantic/AppShell.tsx +30 -0
  54. package/src/tui/semantic/CommandBrowserScreen.tsx +16 -0
  55. package/src/tui/semantic/ConfigScreen.tsx +23 -0
  56. package/src/tui/semantic/EditorScreen.tsx +20 -0
  57. package/src/tui/semantic/LogsScreen.tsx +9 -0
  58. package/src/tui/semantic/RunningScreen.tsx +17 -0
  59. package/src/tui/semantic/layoutTypes.ts +72 -0
  60. package/src/tui/semantic/render.tsx +44 -0
  61. package/src/tui/semantic/types.ts +31 -98
  62. package/src/tui/utils/jsonTokenizer.ts +98 -0
  63. package/src/tui/utils/schemaToFields.ts +1 -25
  64. package/.devcontainer/devcontainer.json +0 -19
  65. package/.devcontainer/install-prerequisites.sh +0 -49
  66. package/.github/workflows/copilot-setup-steps.yml +0 -32
  67. package/.github/workflows/pull-request.yml +0 -27
  68. package/.github/workflows/release-npm-package.yml +0 -81
  69. package/AGENTS.md +0 -43
  70. package/CLAUDE.md +0 -1
  71. package/bun.lock +0 -321
  72. package/examples/tui-app/commands/config/app/get.ts +0 -62
  73. package/examples/tui-app/commands/config/app/index.ts +0 -23
  74. package/examples/tui-app/commands/config/app/set.ts +0 -96
  75. package/examples/tui-app/commands/config/index.ts +0 -28
  76. package/examples/tui-app/commands/config/user/get.ts +0 -61
  77. package/examples/tui-app/commands/config/user/index.ts +0 -23
  78. package/examples/tui-app/commands/config/user/set.ts +0 -57
  79. package/examples/tui-app/commands/greet.ts +0 -78
  80. package/examples/tui-app/commands/math.ts +0 -111
  81. package/examples/tui-app/commands/status.ts +0 -86
  82. package/examples/tui-app/index.ts +0 -38
  83. package/guides/01-hello-world.md +0 -101
  84. package/guides/02-adding-options.md +0 -103
  85. package/guides/03-multiple-commands.md +0 -161
  86. package/guides/04-subcommands.md +0 -206
  87. package/guides/05-interactive-tui.md +0 -209
  88. package/guides/06-config-validation.md +0 -256
  89. package/guides/07-async-cancellation.md +0 -334
  90. package/guides/08-complete-application.md +0 -507
  91. package/guides/README.md +0 -78
  92. package/src/tui/adapters/ink/components/Code.tsx +0 -6
  93. package/src/tui/adapters/ink/components/Container.tsx +0 -5
  94. package/src/tui/adapters/ink/components/Spacer.tsx +0 -15
  95. package/src/tui/adapters/ink/components/Value.tsx +0 -7
  96. package/src/tui/adapters/opentui/components/Code.tsx +0 -12
  97. package/src/tui/adapters/opentui/components/Container.tsx +0 -56
  98. package/src/tui/adapters/opentui/components/Spacer.tsx +0 -5
  99. package/src/tui/adapters/opentui/components/Value.tsx +0 -13
  100. package/src/tui/components/ActionButton.tsx +0 -0
  101. package/src/tui/components/CommandSelector.tsx +0 -119
  102. package/src/tui/components/ConfigForm.tsx +0 -174
  103. package/src/tui/components/FieldRow.tsx +0 -0
  104. package/src/tui/components/Header.tsx +0 -32
  105. package/src/tui/components/ModalBase.tsx +0 -38
  106. package/src/tui/components/ResultsPanel.tsx +0 -84
  107. package/src/tui/components/StatusBar.tsx +0 -44
  108. package/src/tui/components/logColors.ts +0 -12
  109. package/src/tui/components/types.ts +0 -30
  110. package/src/tui/context/ClipboardContext.tsx +0 -87
  111. package/src/tui/context/KeyboardContext.tsx +0 -132
  112. package/src/tui/hooks/useActiveKeyHandler.ts +0 -75
  113. package/src/tui/hooks/useClipboard.ts +0 -81
  114. package/src/tui/hooks/useClipboardProvider.ts +0 -42
  115. package/src/tui/hooks/useGlobalKeyHandler.ts +0 -54
  116. package/src/tui/modals/CliModal.tsx +0 -82
  117. package/src/tui/modals/EditorModal.tsx +0 -207
  118. package/src/tui/modals/LogsModal.tsx +0 -98
  119. package/src/tui/registry.ts +0 -102
  120. package/src/tui/screens/CommandSelectScreen.tsx +0 -162
  121. package/src/tui/screens/ConfigScreen.tsx +0 -160
  122. package/src/tui/screens/ErrorScreen.tsx +0 -58
  123. package/src/tui/screens/ResultsScreen.tsx +0 -60
  124. package/src/tui/screens/RunningScreen.tsx +0 -72
  125. package/src/tui/screens/ScreenBase.ts +0 -6
  126. package/src/tui/semantic/Button.tsx +0 -7
  127. package/src/tui/semantic/Code.tsx +0 -7
  128. package/src/tui/semantic/CodeHighlight.tsx +0 -7
  129. package/src/tui/semantic/Container.tsx +0 -7
  130. package/src/tui/semantic/Field.tsx +0 -7
  131. package/src/tui/semantic/Label.tsx +0 -7
  132. package/src/tui/semantic/MenuButton.tsx +0 -7
  133. package/src/tui/semantic/MenuItem.tsx +0 -7
  134. package/src/tui/semantic/Overlay.tsx +0 -7
  135. package/src/tui/semantic/Panel.tsx +0 -7
  136. package/src/tui/semantic/ScrollView.tsx +0 -9
  137. package/src/tui/semantic/Select.tsx +0 -7
  138. package/src/tui/semantic/Spacer.tsx +0 -7
  139. package/src/tui/semantic/Spinner.tsx +0 -7
  140. package/src/tui/semantic/TextInput.tsx +0 -7
  141. package/src/tui/semantic/Value.tsx +0 -7
  142. package/tsconfig.json +0 -25
@@ -1,72 +0,0 @@
1
- import { useCallback } from "react";
2
- import type { AnyCommand } from "../../core/command.ts";
3
- import { useNavigation } from "../context/NavigationContext.tsx";
4
- import { useExecutor } from "../context/ExecutorContext.tsx";
5
- import { useBackHandler } from "../hooks/useBackHandler.ts";
6
- import type { ScreenComponent } from "../registry.ts";
7
- import { ScreenBase } from "./ScreenBase.ts";
8
- import { Container } from "../semantic/Container.tsx";
9
- import { Label } from "../semantic/Label.tsx";
10
- import { Panel } from "../semantic/Panel.tsx";
11
-
12
- /**
13
- * Screen state stored in navigation params.
14
- */
15
- export interface RunningParams {
16
- command: AnyCommand;
17
- commandPath: string[];
18
- values: Record<string, unknown>;
19
- }
20
-
21
- /**
22
- * Running screen - shows while a command is executing.
23
- * Fully self-contained - gets all data from context and handles its own transitions.
24
- */
25
- export class RunningScreen extends ScreenBase {
26
- static readonly Id = "running";
27
- getRoute(): string {
28
- return RunningScreen.Id;
29
- }
30
-
31
- override component(): ScreenComponent {
32
- return function RunningScreenComponent() {
33
- const navigation = useNavigation();
34
- const executor = useExecutor();
35
-
36
- // Get params from navigation
37
- const params = navigation.current.params as RunningParams | undefined;
38
- if (!params) return null;
39
-
40
- const { command } = params;
41
-
42
- // Register back handler - cancel execution on back
43
- useBackHandler(useCallback(() => {
44
- if (executor.isExecuting) {
45
- executor.cancel();
46
- executor.reset();
47
- // Pop back to config screen
48
- navigation.pop();
49
- return true;
50
- }
51
- return false;
52
- }, [executor, navigation]));
53
-
54
- return (
55
- <Panel
56
- flexDirection="column"
57
- flex={1}
58
- title={`Running ${command.displayName ?? command.name}`}
59
- padding={1}
60
- focused
61
- >
62
- <Container flexDirection="column" flex={1} gap={1}>
63
- <Label color="mutedText">
64
- Check logs for progress.
65
- </Label>
66
- <Label color="mutedText">Press Esc to cancel.</Label>
67
- </Container>
68
- </Panel>
69
- );
70
- };
71
- }
72
- }
@@ -1,6 +0,0 @@
1
- import type { ScreenComponent } from "../registry";
2
-
3
- export abstract class ScreenBase {
4
- abstract component(): ScreenComponent;
5
- abstract getRoute(): string;
6
- }
@@ -1,7 +0,0 @@
1
- import type { ButtonProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Button(props: ButtonProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Button(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { CodeProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Code(props: CodeProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Code(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { CodeHighlightProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function CodeHighlight(props: CodeHighlightProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.CodeHighlight(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { ContainerProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Container(props: ContainerProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Container(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { FieldProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Field(props: FieldProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Field(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { LabelProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Label(props: LabelProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Label(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { MenuButtonProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function MenuButton(props: MenuButtonProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.MenuButton(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { MenuItemProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function MenuItem(props: MenuItemProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.MenuItem(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { OverlayProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Overlay(props: OverlayProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Overlay(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { PanelProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Panel(props: PanelProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Panel(props);
7
- }
@@ -1,9 +0,0 @@
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 };
@@ -1,7 +0,0 @@
1
- import type { SelectProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Select(props: SelectProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Select(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { SpacerProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Spacer(props: SpacerProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Spacer(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { SpinnerProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Spinner(props: SpinnerProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Spinner(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { TextInputProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function TextInput(props: TextInputProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.TextInput(props);
7
- }
@@ -1,7 +0,0 @@
1
- import type { ValueProps } from "./types.ts";
2
- import { useRenderer } from "../context/RendererContext.tsx";
3
-
4
- export function Value(props: ValueProps) {
5
- const renderer = useRenderer();
6
- return renderer.components.Value(props);
7
- }
package/tsconfig.json DELETED
@@ -1,25 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "lib": ["ESNext"],
4
- "target": "ESNext",
5
- "module": "ESNext",
6
- "moduleDetection": "force",
7
- "jsx": "react-jsx",
8
- "jsxImportSource": "@opentui/react",
9
- "allowJs": true,
10
- "moduleResolution": "bundler",
11
- "allowImportingTsExtensions": true,
12
- "verbatimModuleSyntax": true,
13
- "noEmit": true,
14
- "strict": true,
15
- "skipLibCheck": true,
16
- "noFallthroughCasesInSwitch": true,
17
- "noUnusedLocals": true,
18
- "noUnusedParameters": true,
19
- "noPropertyAccessFromIndexSignature": true,
20
- "noUncheckedIndexedAccess": true,
21
- "esModuleInterop": true,
22
- "types": ["bun"]
23
- },
24
- "include": ["src/**/*", "examples/**/*"]
25
- }