Skip to content

Commit ffee16a

Browse files
ok
1 parent d1f8ac1 commit ffee16a

File tree

1 file changed

+96
-41
lines changed

1 file changed

+96
-41
lines changed

apps/cli/src/tui/app.tsx

Lines changed: 96 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -526,14 +526,33 @@ export async function renderTui(options: TuiOptions): Promise<void> {
526526

527527
return new Promise((resolve) => {
528528
const handleExit = () => {
529+
// Clean up the renderer before exiting (following opencode pattern)
530+
try {
531+
renderer.destroy();
532+
} catch {
533+
// Ignore errors during cleanup
534+
}
529535
options.onCancel();
536+
resolve();
530537
process.exit(0);
531538
};
532539

540+
// Handle SIGINT (Ctrl+C) for clean exit
541+
process.on("SIGINT", handleExit);
542+
533543
createRoot(renderer).render(
534544
<App
535545
initialConfig={options.initialConfig}
536-
onComplete={options.onComplete}
546+
onComplete={async (config) => {
547+
await options.onComplete(config);
548+
// Clean up after successful completion
549+
try {
550+
renderer.destroy();
551+
} catch {
552+
// Ignore errors during cleanup
553+
}
554+
resolve();
555+
}}
537556
onExit={handleExit}
538557
/>,
539558
);
@@ -717,13 +736,13 @@ function App(props: {
717736
<box style={{ width, height, backgroundColor: theme.bg, flexDirection: "column" }}>
718737
<box
719738
style={{
720-
height: 5,
739+
height: 6,
721740
justifyContent: "center",
722741
alignItems: "center",
723742
backgroundColor: theme.surface,
724743
}}
725744
>
726-
<ascii-font text="Better T Stack" font="tiny" />
745+
<ascii-font text="Better T Stack" font="block" />
727746
</box>
728747

729748
<box
@@ -735,11 +754,12 @@ function App(props: {
735754
overflow: "scroll",
736755
}}
737756
>
738-
{/* Prompts Phase */}
757+
{/* Prompts Phase - Sequential like clack */}
739758
{phase === "prompts" && (
740-
<>
759+
<box style={{ flexDirection: "column" }}>
760+
{/* Completed steps - compact list */}
741761
{visibleSteps.slice(0, currentVisibleIndex).map(({ step }) => (
742-
<box key={step.id} style={{ flexDirection: "row" }}>
762+
<box key={step.id} style={{ flexDirection: "row", marginBottom: 0 }}>
743763
<text>
744764
<span fg={theme.success}></span>
745765
<span fg={theme.muted}> {step.title}: </span>
@@ -748,8 +768,9 @@ function App(props: {
748768
</box>
749769
))}
750770

771+
{/* Current step - prominent with spacing */}
751772
{!completed && currentStep && (
752-
<box style={{ marginTop: 1 }}>
773+
<box style={{ marginTop: currentVisibleIndex > 0 ? 1 : 0, flexDirection: "column" }}>
753774
<box style={{ flexDirection: "row", marginBottom: 1 }}>
754775
<text>
755776
<span fg={theme.primary}></span>
@@ -805,23 +826,15 @@ function App(props: {
805826
</box>
806827
)}
807828

829+
{/* Confirmation step */}
808830
{completed && (
809831
<ConfirmStep
810832
config={config}
811833
onComplete={handleComplete}
812834
onBack={() => setCompleted(false)}
813835
/>
814836
)}
815-
816-
{!completed &&
817-
visibleSteps.slice(currentVisibleIndex + 1).map(({ step }) => (
818-
<box key={step.id} style={{ flexDirection: "row" }}>
819-
<text>
820-
<span fg={theme.muted}>{step.title}</span>
821-
</text>
822-
</box>
823-
))}
824-
</>
837+
</box>
825838
)}
826839

827840
{/* Creating Phase - Show spinner and logs */}
@@ -905,34 +918,76 @@ function App(props: {
905918
</span>
906919
</text>
907920
</box>
908-
909-
<box style={{ marginTop: 3 }}>
910-
<text>
911-
<span fg={theme.muted}>Press any key to exit...</span>
912-
</text>
913-
</box>
914921
</box>
915922
)}
916923
</box>
917924

918-
<box
919-
style={{
920-
height: 1,
921-
backgroundColor: theme.surface,
922-
paddingLeft: 2,
923-
paddingRight: 2,
924-
flexDirection: "row",
925-
justifyContent: "space-between",
926-
}}
927-
>
928-
<text>
929-
<span fg={theme.muted}>ctrl+c</span>
930-
<span fg={theme.subtext}> exit</span>
931-
</text>
932-
<text>
933-
<span fg={theme.primary}>better-t-stack.dev</span>
934-
</text>
935-
</box>
925+
{/* Status Bar */}
926+
<StatusBar phase={phase} canGoBack={stepIndex > 0} />
927+
</box>
928+
);
929+
}
930+
931+
// Version from package.json
932+
const VERSION = "3.11.0";
933+
934+
// Status bar component showing keybinds and version
935+
function StatusBar(props: { phase: Phase; canGoBack: boolean }) {
936+
const keybinds = () => {
937+
switch (props.phase) {
938+
case "prompts":
939+
return (
940+
<>
941+
<span fg={theme.muted}>↑↓</span>
942+
<span fg={theme.subtext}> navigate </span>
943+
<span fg={theme.muted}></span>
944+
<span fg={theme.subtext}> select </span>
945+
{props.canGoBack && (
946+
<>
947+
<span fg={theme.muted}>esc</span>
948+
<span fg={theme.subtext}> back </span>
949+
</>
950+
)}
951+
<span fg={theme.muted}>ctrl+c</span>
952+
<span fg={theme.subtext}> exit</span>
953+
</>
954+
);
955+
case "creating":
956+
return (
957+
<>
958+
<span fg={theme.muted}>ctrl+c</span>
959+
<span fg={theme.subtext}> cancel</span>
960+
</>
961+
);
962+
case "done":
963+
return (
964+
<>
965+
<span fg={theme.muted}>any key</span>
966+
<span fg={theme.subtext}> exit</span>
967+
</>
968+
);
969+
}
970+
};
971+
972+
return (
973+
<box
974+
style={{
975+
height: 1,
976+
backgroundColor: theme.surface,
977+
paddingLeft: 2,
978+
paddingRight: 2,
979+
flexDirection: "row",
980+
justifyContent: "space-between",
981+
alignItems: "center",
982+
}}
983+
>
984+
<text>
985+
<span fg={theme.muted}>v{VERSION}</span>
986+
</text>
987+
<text>{keybinds()}</text>
988+
<text>
989+
<span fg={theme.primary}>better-t-stack.dev</span>
990+
</text>
936991
</box>
937992
);
938993
}

0 commit comments

Comments
 (0)