1- // Copyright 2025 , Command Line Inc.
1+ // Copyright 2026 , Command Line Inc.
22// SPDX-License-Identifier: Apache-2.0
33
44import Logo from "@/app/asset/logo.svg" ;
55import { Button } from "@/app/element/button" ;
66import { FlexiModal } from "@/app/modals/modal" ;
7- import { CurrentOnboardingVersion } from "@/app/onboarding/onboarding-common" ;
7+ import { CurrentOnboardingVersion , OnboardingGradientBg } from "@/app/onboarding/onboarding-common" ;
88import { OnboardingFeatures } from "@/app/onboarding/onboarding-features" ;
99import { ClientModel } from "@/app/store/client-model" ;
1010import { globalStore } from "@/app/store/global" ;
@@ -17,6 +17,84 @@ import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
1717import { useEffect , useRef , useState } from "react" ;
1818import { debounce } from "throttle-debounce" ;
1919
20+ type UpgradeMinorWelcomePageProps = {
21+ onStarClick : ( ) => void ;
22+ onAlreadyStarred : ( ) => void ;
23+ onMaybeLater : ( ) => void ;
24+ } ;
25+
26+ const UpgradeMinorWelcomePage = ( { onStarClick, onAlreadyStarred, onMaybeLater } : UpgradeMinorWelcomePageProps ) => {
27+ return (
28+ < div className = "flex flex-col h-full" >
29+ < header className = "flex flex-col gap-2 border-b-0 p-0 mt-1 mb-4 w-full unselectable flex-shrink-0" >
30+ < div className = "flex justify-center" >
31+ < Logo />
32+ </ div >
33+ < div className = "text-center text-[25px] font-normal text-foreground" > Welcome to Wave v0.14!</ div >
34+ </ header >
35+ < OverlayScrollbarsComponent
36+ className = "flex-1 overflow-y-auto min-h-0"
37+ options = { { scrollbars : { autoHide : "never" } } }
38+ >
39+ < div className = "flex flex-col items-center gap-3 w-full mb-2 unselectable" >
40+ < div className = "flex flex-col items-center gap-4" >
41+ < div className = "flex flex-row gap-4 items-center" >
42+ < div className = "flex h-[52px] px-3 items-center rounded-lg bg-hover text-accent text-[24px]" >
43+ < i className = "fa fa-sparkles" />
44+ < span className = "font-bold ml-2 font-mono" > Wave AI</ span >
45+ </ div >
46+ < div className = "flex h-[52px] px-3 items-center rounded-lg bg-hover text-[18px]" >
47+ < i className = "fa-sharp fa-solid fa-shield text-sky-500" />
48+ < span className = "font-bold ml-2 text-accent" > Durable SSH Sessions</ span >
49+ </ div >
50+ </ div >
51+ < div className = "text-secondary leading-relaxed max-w-[600px] text-left" >
52+ < p className = "mb-4" >
53+ Wave AI is your terminal assistant with full context. It can read your terminal output,
54+ analyze widgets, read and write files, and help you solve problems faster.
55+ </ p >
56+ < p className = "mb-4" >
57+ < span className = "font-semibold text-foreground" > New in v0.13:</ span > Wave AI now
58+ supports local models and bring-your-own-key! Use Ollama, LM Studio, vLLM, OpenRouter,
59+ or any OpenAI-compatible provider.
60+ </ p >
61+ < p className = "mb-4" >
62+ < span className = "font-semibold text-foreground" > New in v0.14:</ span > Durable SSH
63+ sessions survive network drops, laptop sleep, and restarts — all without tmux or screen.
64+ </ p >
65+ </ div >
66+ </ div >
67+
68+ < div className = "w-full max-w-[550px] border-t border-border my-2" > </ div >
69+
70+ < div className = "flex flex-col items-center gap-3 text-center max-w-[550px]" >
71+ < div className = "text-foreground text-base" > Thanks for being an early Wave adopter! ⭐</ div >
72+ < div className = "text-secondary text-sm text-left" >
73+ A GitHub star shows your support for Wave (and open-source) and helps us reach more
74+ developers.
75+ </ div >
76+ </ div >
77+ </ div >
78+ </ OverlayScrollbarsComponent >
79+ < footer className = "unselectable flex-shrink-0 mt-4" >
80+ < div className = "flex flex-row items-center justify-center gap-2.5 [&>button]:!px-5 [&>button]:!py-2 [&>button]:text-sm [&>button]:!h-[37px]" >
81+ < Button className = "outlined grey font-[600]" onClick = { onAlreadyStarred } >
82+ 🙏 Already Starred
83+ </ Button >
84+ < Button className = "outlined green font-[600]" onClick = { onStarClick } >
85+ ⭐ Star Now
86+ </ Button >
87+ < Button className = "outlined grey font-[600]" onClick = { onMaybeLater } >
88+ Maybe Later
89+ </ Button >
90+ </ div >
91+ </ footer >
92+ </ div >
93+ ) ;
94+ } ;
95+
96+ UpgradeMinorWelcomePage . displayName = "UpgradeMinorWelcomePage" ;
97+
2098const UpgradeOnboardingMinor = ( ) => {
2199 const modalRef = useRef < HTMLDivElement | null > ( null ) ;
22100 const [ pageName , setPageName ] = useState < "welcome" | "features" > ( "welcome" ) ;
@@ -57,7 +135,7 @@ const UpgradeOnboardingMinor = () => {
57135 TabRpcClient ,
58136 {
59137 event : "onboarding:githubstar" ,
60- props : { "onboarding:githubstar" : "star" } ,
138+ props : { "onboarding:githubstar" : "star" , "onboarding:page" : "minorupgrade" } ,
61139 } ,
62140 { noresponse : true }
63141 ) ;
@@ -75,7 +153,7 @@ const UpgradeOnboardingMinor = () => {
75153 TabRpcClient ,
76154 {
77155 event : "onboarding:githubstar" ,
78- props : { "onboarding:githubstar" : "already" } ,
156+ props : { "onboarding:githubstar" : "already" , "onboarding:page" : "minorupgrade" } ,
79157 } ,
80158 { noresponse : true }
81159 ) ;
@@ -92,7 +170,7 @@ const UpgradeOnboardingMinor = () => {
92170 TabRpcClient ,
93171 {
94172 event : "onboarding:githubstar" ,
95- props : { "onboarding:githubstar" : "later" } ,
173+ props : { "onboarding:githubstar" : "later" , "onboarding:page" : "minorupgrade" } ,
96174 } ,
97175 { noresponse : true }
98176 ) ;
@@ -119,73 +197,11 @@ const UpgradeOnboardingMinor = () => {
119197 let pageComp : React . JSX . Element = null ;
120198 if ( pageName === "welcome" ) {
121199 pageComp = (
122- < div className = "flex flex-col h-full" >
123- < header className = "flex flex-col gap-2 border-b-0 p-0 mt-1 mb-4 w-full unselectable flex-shrink-0" >
124- < div className = "flex justify-center" >
125- < Logo />
126- </ div >
127- < div className = "text-center text-[25px] font-normal text-foreground" > Welcome to Wave v0.14!</ div >
128- </ header >
129- < OverlayScrollbarsComponent
130- className = "flex-1 overflow-y-auto min-h-0"
131- options = { { scrollbars : { autoHide : "never" } } }
132- >
133- < div className = "flex flex-col items-center gap-3 w-full mb-2 unselectable" >
134- < div className = "flex flex-col items-center gap-4" >
135- < div className = "flex flex-row gap-4 items-center" >
136- < div className = "flex h-[52px] px-3 items-center rounded-lg bg-hover text-accent text-[24px]" >
137- < i className = "fa fa-sparkles" />
138- < span className = "font-bold ml-2 font-mono" > Wave AI</ span >
139- </ div >
140- < div className = "flex h-[52px] px-3 items-center rounded-lg bg-hover text-[18px]" >
141- < i className = "fa-sharp fa-solid fa-shield text-sky-500" />
142- < span className = "font-bold ml-2 text-accent" > Durable SSH Sessions</ span >
143- </ div >
144- </ div >
145- < div className = "text-secondary leading-relaxed max-w-[600px] text-left" >
146- < p className = "mb-4" >
147- Wave AI is your terminal assistant with full context. It can read your terminal
148- output, analyze widgets, read and write files, and help you solve
149- problems faster.
150- </ p >
151- < p className = "mb-4" >
152- < span className = "font-semibold text-foreground" > New in v0.13:</ span > Wave AI now
153- supports local models and bring-your-own-key! Use Ollama, LM Studio, vLLM,
154- OpenRouter, or any OpenAI-compatible provider.
155- </ p >
156- < p className = "mb-4" >
157- < span className = "font-semibold text-foreground" > New in v0.14:</ span > Durable SSH
158- sessions survive network drops, laptop sleep, and restarts — all without tmux or
159- screen.
160- </ p >
161- </ div >
162- </ div >
163-
164- < div className = "w-full max-w-[550px] border-t border-border my-2" > </ div >
165-
166- < div className = "flex flex-col items-center gap-3 text-center max-w-[550px]" >
167- < div className = "text-foreground text-base" > Thanks for being an early Wave adopter! ⭐</ div >
168- < div className = "text-secondary text-sm text-left" >
169- A GitHub star shows your support for Wave (and open-source) and helps us reach more
170- developers.
171- </ div >
172- </ div >
173- </ div >
174- </ OverlayScrollbarsComponent >
175- < footer className = "unselectable flex-shrink-0 mt-4" >
176- < div className = "flex flex-row items-center justify-center gap-2.5 [&>button]:!px-5 [&>button]:!py-2 [&>button]:text-sm [&>button]:!h-[37px]" >
177- < Button className = "outlined grey font-[600]" onClick = { handleAlreadyStarred } >
178- 🙏 Already Starred
179- </ Button >
180- < Button className = "outlined green font-[600]" onClick = { handleStarClick } >
181- ⭐ Star Now
182- </ Button >
183- < Button className = "outlined grey font-[600]" onClick = { handleMaybeLater } >
184- Maybe Later
185- </ Button >
186- </ div >
187- </ footer >
188- </ div >
200+ < UpgradeMinorWelcomePage
201+ onStarClick = { handleStarClick }
202+ onAlreadyStarred = { handleAlreadyStarred }
203+ onMaybeLater = { handleMaybeLater }
204+ />
189205 ) ;
190206 } else if ( pageName === "features" ) {
191207 pageComp = < OnboardingFeatures onComplete = { handleFeaturesComplete } /> ;
@@ -200,12 +216,12 @@ const UpgradeOnboardingMinor = () => {
200216
201217 return (
202218 < FlexiModal className = { `${ widthClass } rounded-[10px] ${ paddingClass } relative overflow-hidden` } ref = { modalRef } >
203- < div className = "absolute inset-0 bg-gradient-to-br from-accent/[0.25] via-transparent to-accent/[0.05] pointer-events-none rounded-[10px]" />
219+ < OnboardingGradientBg />
204220 < div className = "flex flex-col w-full h-full relative z-10" > { pageComp } </ div >
205221 </ FlexiModal >
206222 ) ;
207223} ;
208224
209225UpgradeOnboardingMinor . displayName = "UpgradeOnboardingMinor" ;
210226
211- export { UpgradeOnboardingMinor } ;
227+ export { UpgradeMinorWelcomePage , UpgradeOnboardingMinor } ;
0 commit comments