@@ -69,6 +69,11 @@ interface FreebuffLandingScreenProps {
6969 failure : FreebuffSessionFailure | null
7070 lastRefund : number | null
7171 refundPending : boolean
72+ /** True when the CLI was launched with `-c` / `--continue`. Drives the
73+ * "nothing to continue" notice: only a session resume can satisfy the
74+ * user's ask, so the landing screen has to say it found nothing rather
75+ * than behaving like a plain first launch. */
76+ continueRequested ?: boolean
7277}
7378
7479/** Landing-screen heading. Referenced both as rendered text and by the
@@ -77,6 +82,22 @@ interface FreebuffLandingScreenProps {
7782const LANDING_HEADING = 'Start coding for free'
7883const COLLAPSED_LOGO_MIN_HEIGHT = 26
7984
85+ /** Shown on the landing screen when the user launched with `-c` /
86+ * `--continue` but the probe found no active session to resume (no seat,
87+ * expired, or explicitly ended). Exported so the render test can mount it
88+ * without the landing screen's ad/streak/logo machinery. */
89+ export const NOTHING_TO_CONTINUE_MESSAGE =
90+ "There's nothing to continue — no active session was found. Pick a model below to start a new one."
91+
92+ export const FreebuffNothingToContinueNotice : React . FC = ( ) => {
93+ const theme = useTheme ( )
94+ return (
95+ < text style = { { fg : theme . secondary , wrapMode : 'word' , marginTop : 1 } } >
96+ { NOTHING_TO_CONTINUE_MESSAGE }
97+ </ text >
98+ )
99+ }
100+
80101/** "in ~3h 20m" / "in ~45 min" / "in under a minute". Used on the
81102 * rate-limited screen so users know when they can try again. */
82103const formatRetryAfter = ( ms : number ) : string => {
@@ -358,6 +379,7 @@ export const FreebuffLandingScreen: React.FC<FreebuffLandingScreenProps> = ({
358379 failure,
359380 lastRefund,
360381 refundPending,
382+ continueRequested,
361383} ) => {
362384 const theme = useTheme ( )
363385 const renderer = useRenderer ( )
@@ -593,9 +615,18 @@ export const FreebuffLandingScreen: React.FC<FreebuffLandingScreenProps> = ({
593615 // scrollbox is measured by the selector itself and must NOT be reserved
594616 // here as well, or the viewport shrinks while the content grows.
595617 const belowPickerRows = streakRows + noticeRows + streakBonusRows
618+ // The continue notice renders above the picker, so its rows must be carved
619+ // out of the picker's viewport budget the way the heading's are.
620+ const continueNoticeRows =
621+ continueRequested && isLanding
622+ ? 1 /* marginTop */ + wrappedRows ( NOTHING_TO_CONTINUE_MESSAGE )
623+ : 0
596624 const reservedChrome = 2 + adRows + 1 /* main paddingBottom */ + logoBlockRows
597625 const landingTextRows =
598- wrappedRows ( LANDING_HEADING ) + textMarginBottom + belowPickerRows
626+ wrappedRows ( LANDING_HEADING ) +
627+ textMarginBottom +
628+ continueNoticeRows +
629+ belowPickerRows
599630 // Floor = one whole recommended card: 2 border rows + its 2 text lines (name
600631 // + tagline, then the AI-training warning on its own line). Rows grew from
601632 // one text line to two when the warning stopped inlining, so the old floor of
@@ -726,6 +757,7 @@ export const FreebuffLandingScreen: React.FC<FreebuffLandingScreenProps> = ({
726757 onDismiss = { freebucksIntro . dismiss }
727758 />
728759 ) }
760+ { continueRequested && < FreebuffNothingToContinueNotice /> }
729761 < LandingHeadingRow
730762 streakLine = { streakOnHeadingRow ? streakLine : null }
731763 marginBottom = { textMarginBottom }
0 commit comments