diff --git a/src/components/LogoV2/WelcomeV2.tsx b/src/components/LogoV2/WelcomeV2.tsx
index ba6cf82127..54b7064dc8 100644
--- a/src/components/LogoV2/WelcomeV2.tsx
+++ b/src/components/LogoV2/WelcomeV2.tsx
@@ -1,433 +1,21 @@
-import { c as _c } from "react-compiler-runtime";
-import React from 'react';
-import { Box, Text, useTheme } from 'src/ink.js';
-import { env } from '../../utils/env.js';
-const WELCOME_V2_WIDTH = 58;
-export function WelcomeV2() {
- const $ = _c(35);
- const [theme] = useTheme();
- if (env.terminal === "Apple_Terminal") {
- let t0;
- if ($[0] !== theme) {
- // VERBOO-BRAND: welcome message
- t0 = ;
- $[0] = theme;
- $[1] = t0;
- } else {
- t0 = $[1];
- }
- return t0;
- }
- if (["light", "light-daltonized", "light-ansi"].includes(theme)) {
- let t0;
- let t1;
- let t2;
- let t3;
- let t4;
- let t5;
- let t6;
- let t7;
- let t8;
- if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
- t0 = {"Welcome to Verboo Code"} v{MACRO.DISPLAY_VERSION ?? MACRO.VERSION} ;
- t1 = {"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"};
- t2 = {" "};
- t3 = {" "};
- t4 = {" "};
- t5 = {" \u2591\u2591\u2591\u2591\u2591\u2591 "};
- t6 = {" \u2591\u2591\u2591 \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "};
- t7 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "};
- t8 = {" "};
- $[2] = t0;
- $[3] = t1;
- $[4] = t2;
- $[5] = t3;
- $[6] = t4;
- $[7] = t5;
- $[8] = t6;
- $[9] = t7;
- $[10] = t8;
- } else {
- t0 = $[2];
- t1 = $[3];
- t2 = $[4];
- t3 = $[5];
- t4 = $[6];
- t5 = $[7];
- t6 = $[8];
- t7 = $[9];
- t8 = $[10];
- }
- let t9;
- if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
- t9 = {" \u2591\u2591\u2591\u2591"}{" \u2588\u2588 "};
- $[11] = t9;
- } else {
- t9 = $[11];
- }
- let t10;
- let t11;
- if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
- t10 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591"}{" \u2588\u2588\u2592\u2592\u2588\u2588 "};
- t11 = {" \u2592\u2592 \u2588\u2588 \u2592"};
- $[12] = t10;
- $[13] = t11;
- } else {
- t10 = $[12];
- t11 = $[13];
- }
- let t12;
- if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
- t12 = {" "}{" "}{" \u2592\u2592\u2591\u2591\u2592\u2592 \u2592 \u2592\u2592"};
- $[14] = t12;
- } else {
- t12 = $[14];
- }
- let t13;
- if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
- t13 = {" "}{" π» "}{" \u2592\u2592 \u2592\u2592 "};
- $[15] = t13;
- } else {
- t13 = $[15];
- }
- let t14;
- if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
- t14 = {" "}{" "}{" \u2591 \u2592 "};
- $[16] = t14;
- } else {
- t14 = $[16];
- }
- let t15;
- if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
- t15 = {t0}{t1}{t2}{t3}{t4}{t5}{t6}{t7}{t8}{t9}{t10}{t11}{t12}{t13}{t14}{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026"}{" "}{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2591\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2592\u2026\u2026\u2026\u2026"};
- $[17] = t15;
- } else {
- t15 = $[17];
- }
- return t15;
- }
- let t0;
- let t1;
- let t2;
- let t3;
- let t4;
- let t5;
- let t6;
- if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
- t0 = {"Welcome to Verboo Code"} v{MACRO.DISPLAY_VERSION ?? MACRO.VERSION} ;
- t1 = {"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"};
- t2 = {" "};
- t3 = {" * \u2588\u2588\u2588\u2588\u2588\u2593\u2593\u2591 "};
- t4 = {" * \u2588\u2588\u2588\u2593\u2591 \u2591\u2591 "};
- t5 = {" \u2591\u2591\u2591\u2591\u2591\u2591 \u2588\u2588\u2588\u2593\u2591 "};
- t6 = {" \u2591\u2591\u2591 \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 \u2588\u2588\u2588\u2593\u2591 "};
- $[18] = t0;
- $[19] = t1;
- $[20] = t2;
- $[21] = t3;
- $[22] = t4;
- $[23] = t5;
- $[24] = t6;
- } else {
- t0 = $[18];
- t1 = $[19];
- t2 = $[20];
- t3 = $[21];
- t4 = $[22];
- t5 = $[23];
- t6 = $[24];
- }
- let t10;
- let t11;
- let t7;
- let t8;
- let t9;
- if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
- t7 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "}*{" \u2588\u2588\u2593\u2591\u2591 \u2593 "};
- t8 = {" \u2591\u2593\u2593\u2588\u2588\u2588\u2593\u2593\u2591 "};
- t9 = {" * \u2591\u2591\u2591\u2591 "};
- t10 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "};
- t11 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "};
- $[25] = t10;
- $[26] = t11;
- $[27] = t7;
- $[28] = t8;
- $[29] = t9;
- } else {
- t10 = $[25];
- t11 = $[26];
- t7 = $[27];
- t8 = $[28];
- t9 = $[29];
- }
- let t12;
- if ($[30] === Symbol.for("react.memo_cache_sentinel")) {
- t12 = {" π» "};
- $[30] = t12;
- } else {
- t12 = $[30];
- }
- let t13;
- if ($[31] === Symbol.for("react.memo_cache_sentinel")) {
- t13 = {" "}{t12}{" "}* ;
- $[31] = t13;
- } else {
- t13 = $[31];
- }
- let t14;
- if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
- t14 = {" "}{" "}{" "}*{" "};
- $[32] = t14;
- } else {
- t14 = $[32];
- }
- let t15;
- if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
- t15 = {" "}{" "}{" * "};
- $[33] = t15;
- } else {
- t15 = $[33];
- }
- let t16;
- if ($[34] === Symbol.for("react.memo_cache_sentinel")) {
- t16 = {t0}{t1}{t2}{t3}{t4}{t5}{t6}{t7}{t8}{t9}{t10}{t11}{t13}{t14}{t15}{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026"}{" "}{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"};
- $[34] = t16;
- } else {
- t16 = $[34];
- }
- return t16;
-}
-type AppleTerminalWelcomeV2Props = {
- theme: string;
- welcomeMessage: string;
-};
-function AppleTerminalWelcomeV2(t0) {
- const $ = _c(44);
- const {
- theme,
- welcomeMessage
- } = t0;
- const isLightTheme = ["light", "light-daltonized", "light-ansi"].includes(theme);
- if (isLightTheme) {
- let t1;
- if ($[0] !== welcomeMessage) {
- t1 = {welcomeMessage} ;
- $[0] = welcomeMessage;
- $[1] = t1;
- } else {
- t1 = $[1];
- }
- let t2;
- if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
- t2 = v{MACRO.DISPLAY_VERSION ?? MACRO.VERSION} ;
- $[2] = t2;
- } else {
- t2 = $[2];
- }
- let t3;
- if ($[3] !== t1) {
- t3 = {t1}{t2};
- $[3] = t1;
- $[4] = t3;
- } else {
- t3 = $[4];
- }
- let t10;
- let t11;
- let t4;
- let t5;
- let t6;
- let t7;
- let t8;
- let t9;
- if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
- t4 = {"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"};
- t5 = {" "};
- t6 = {" "};
- t7 = {" "};
- t8 = {" \u2591\u2591\u2591\u2591\u2591\u2591 "};
- t9 = {" \u2591\u2591\u2591 \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "};
- t10 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "};
- t11 = {" "};
- $[5] = t10;
- $[6] = t11;
- $[7] = t4;
- $[8] = t5;
- $[9] = t6;
- $[10] = t7;
- $[11] = t8;
- $[12] = t9;
- } else {
- t10 = $[5];
- t11 = $[6];
- t4 = $[7];
- t5 = $[8];
- t6 = $[9];
- t7 = $[10];
- t8 = $[11];
- t9 = $[12];
- }
- let t12;
- if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
- t12 = {" \u2591\u2591\u2591\u2591"}{" \u2588\u2588 "};
- $[13] = t12;
- } else {
- t12 = $[13];
- }
- let t13;
- let t14;
- let t15;
- if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
- t13 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591"}{" \u2588\u2588\u2592\u2592\u2588\u2588 "};
- t14 = {" \u2592\u2592 \u2588\u2588 \u2592"};
- t15 = {" \u2592\u2592\u2591\u2591\u2592\u2592 \u2592 \u2592\u2592"};
- $[14] = t13;
- $[15] = t14;
- $[16] = t15;
- } else {
- t13 = $[14];
- t14 = $[15];
- t15 = $[16];
- }
- let t16;
- if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
- t16 = {" "}{" π» "}{" \u2592\u2592 \u2592\u2592 "};
- $[17] = t16;
- } else {
- t16 = $[17];
- }
- let t17;
- if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
- t17 = {" "}{" "}{" \u2591 \u2592 "};
- $[18] = t17;
- } else {
- t17 = $[18];
- }
- let t18;
- if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
- t18 = {"\u2026\u2026\u2026\u2026\u2026\u2026\u2026"}{" "}{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2591\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2592\u2026\u2026\u2026\u2026"};
- $[19] = t18;
- } else {
- t18 = $[19];
- }
- let t19;
- if ($[20] !== t3) {
- t19 = {t3}{t4}{t5}{t6}{t7}{t8}{t9}{t10}{t11}{t12}{t13}{t14}{t15}{t16}{t17}{t18};
- $[20] = t3;
- $[21] = t19;
- } else {
- t19 = $[21];
- }
- return t19;
- }
- let t1;
- if ($[22] !== welcomeMessage) {
- t1 = {welcomeMessage} ;
- $[22] = welcomeMessage;
- $[23] = t1;
- } else {
- t1 = $[23];
- }
- let t2;
- if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
- t2 = v{MACRO.DISPLAY_VERSION ?? MACRO.VERSION} ;
- $[24] = t2;
- } else {
- t2 = $[24];
- }
- let t3;
- if ($[25] !== t1) {
- t3 = {t1}{t2};
- $[25] = t1;
- $[26] = t3;
- } else {
- t3 = $[26];
- }
- let t4;
- let t5;
- let t6;
- let t7;
- let t8;
- let t9;
- if ($[27] === Symbol.for("react.memo_cache_sentinel")) {
- t4 = {"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"};
- t5 = {" "};
- t6 = {" * \u2588\u2588\u2588\u2588\u2588\u2593\u2593\u2591 "};
- t7 = {" * \u2588\u2588\u2588\u2593\u2591 \u2591\u2591 "};
- t8 = {" \u2591\u2591\u2591\u2591\u2591\u2591 \u2588\u2588\u2588\u2593\u2591 "};
- t9 = {" \u2591\u2591\u2591 \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 \u2588\u2588\u2588\u2593\u2591 "};
- $[27] = t4;
- $[28] = t5;
- $[29] = t6;
- $[30] = t7;
- $[31] = t8;
- $[32] = t9;
- } else {
- t4 = $[27];
- t5 = $[28];
- t6 = $[29];
- t7 = $[30];
- t8 = $[31];
- t9 = $[32];
- }
- let t10;
- let t11;
- let t12;
- let t13;
- let t14;
- if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
- t10 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "}*{" \u2588\u2588\u2593\u2591\u2591 \u2593 "};
- t11 = {" \u2591\u2593\u2593\u2588\u2588\u2588\u2593\u2593\u2591 "};
- t12 = {" * \u2591\u2591\u2591\u2591 "};
- t13 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "};
- t14 = {" \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 "};
- $[33] = t10;
- $[34] = t11;
- $[35] = t12;
- $[36] = t13;
- $[37] = t14;
- } else {
- t10 = $[33];
- t11 = $[34];
- t12 = $[35];
- t13 = $[36];
- t14 = $[37];
- }
- let t15;
- if ($[38] === Symbol.for("react.memo_cache_sentinel")) {
- t15 = {" "}* ;
- $[38] = t15;
- } else {
- t15 = $[38];
- }
- let t16;
- if ($[39] === Symbol.for("react.memo_cache_sentinel")) {
- t16 = {" "}{" π» "}{" "}*{" "};
- $[39] = t16;
- } else {
- t16 = $[39];
- }
- let t17;
- if ($[40] === Symbol.for("react.memo_cache_sentinel")) {
- t17 = {" "}{" "}{" * "};
- $[40] = t17;
- } else {
- t17 = $[40];
- }
- let t18;
- if ($[41] === Symbol.for("react.memo_cache_sentinel")) {
- t18 = {"\u2026\u2026\u2026\u2026\u2026\u2026\u2026"}{" "}{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"};
- $[41] = t18;
- } else {
- t18 = $[41];
- }
- let t19;
- if ($[42] !== t3) {
- t19 = {t3}{t4}{t5}{t6}{t7}{t8}{t9}{t10}{t11}{t12}{t13}{t14}{t15}{t16}{t17}{t18};
- $[42] = t3;
- $[43] = t19;
- } else {
- t19 = $[43];
- }
- return t19;
+import * as React from 'react'
+import { Box, Text } from 'src/ink.js'
+
+export function WelcomeV2(): React.ReactElement {
+ const version = MACRO.DISPLAY_VERSION ?? MACRO.VERSION
+
+ return (
+
+
+ π»
+
+ Verboo Code
+
+ v{version}
+
+
+ Build, debug, and ship from your terminal.
+
+
+ )
}
diff --git a/src/components/PromptInput/PromptInput.tsx b/src/components/PromptInput/PromptInput.tsx
index 8d298ddc91..70cf9010e7 100644
--- a/src/components/PromptInput/PromptInput.tsx
+++ b/src/components/PromptInput/PromptInput.tsx
@@ -1,5 +1,4 @@
import { feature } from 'bun:bundle';
-import chalk from 'chalk';
import * as path from 'path';
import * as React from 'react';
import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';
@@ -2283,7 +2282,7 @@ function PromptInput({
Waiting for permissionβ¦
}
-
+
{mode === 'prompt' && !exitMessage.show && !isPasting ? : }
{swarmBanner ? <>
@@ -2305,7 +2304,7 @@ function PromptInput({
{'β'.repeat(columns)}
> :
-
+
{showFastIcon && {' '}{getFastIconString(true, fastModeCooldown)}{' '}{showFastIconHint && /fast}}
@@ -2369,14 +2368,12 @@ function getInitialPasteId(messages: Message[]): number {
}
return maxId + 1;
}
-function buildBorderText(showFastIcon: boolean, showFastIconHint: boolean, fastModeCooldown: boolean): BorderTextOptions | undefined {
- if (!showFastIcon) return undefined;
- const fastSeg = showFastIconHint ? `${getFastIconString(true, fastModeCooldown)} ${chalk.dim('/fast')}` : getFastIconString(true, fastModeCooldown);
+function buildPromptBorderText(mode: PromptInputMode): BorderTextOptions {
return {
- content: ` ${fastSeg} `,
+ content: mode === 'bash' ? ' shell ' : ' π» ',
position: 'top',
- align: 'end',
- offset: 0
+ align: 'start',
+ offset: 1
};
}
export default React.memo(PromptInput);
diff --git a/src/components/PromptInput/usePromptInputPlaceholder.ts b/src/components/PromptInput/usePromptInputPlaceholder.ts
index 36d8d362b9..99bfbfea9b 100644
--- a/src/components/PromptInput/usePromptInputPlaceholder.ts
+++ b/src/components/PromptInput/usePromptInputPlaceholder.ts
@@ -62,8 +62,10 @@ export function usePromptInputPlaceholder({
promptSuggestionEnabled &&
!proactiveModule?.isProactiveActive()
) {
- return getExampleCommandFromCache()
+ return getExampleCommandFromCache() ?? 'Ask Verboo to build, fix, or explainβ¦'
}
+
+ return 'Ask Verboo to build, fix, or explainβ¦'
}, [
input,
queuedCommands,
diff --git a/src/components/StartupScreen.test.ts b/src/components/StartupScreen.test.ts
index f9eabd0aa0..991f5a6870 100644
--- a/src/components/StartupScreen.test.ts
+++ b/src/components/StartupScreen.test.ts
@@ -193,18 +193,20 @@ describe('renderStartupScreen', () => {
isLocal: false,
}
- test('renders the mascot layout safely in a wide terminal', () => {
+ test('uses the compact ghost identity in a wide terminal', () => {
const output = renderStartupScreen(provider, '0.14.5', '~/project', 120)
const plainOutput = stripAnsi(output)
- expect(plainOutput).toContain('βββββββββ')
+ expect(plainOutput).toContain('π»')
expect(plainOutput).toContain('Verboo Code')
+ expect(plainOutput).not.toContain('βββββββββ')
+ expect(plainOutput).not.toContain('Tokens ilimitados')
expect(output).toContain('\x1b[0m')
expect(output).not.toContain('undefined')
expect(plainOutput.split('\n').every(line => line.length <= 120)).toBe(true)
})
- test('uses the compact header in a narrow terminal', () => {
+ test('keeps the compact identity in a narrow terminal', () => {
const output = stripAnsi(
renderStartupScreen(
{
diff --git a/src/components/StartupScreen.ts b/src/components/StartupScreen.ts
index 2afdfc1cb9..867caf96c2 100644
--- a/src/components/StartupScreen.ts
+++ b/src/components/StartupScreen.ts
@@ -1,9 +1,6 @@
/**
- * VERBOO-BRAND: Verboo Code startup screen β filled-block text logo with
- * Verboo purple gradient. Called once at CLI startup before the Ink UI renders.
- *
- * NOTE: cores aqui sΓ£o RGB hardcoded (NΓO usam theme.ts) β toda mudanΓ§a
- * de marca neste arquivo Γ© manual.
+ * Minimal Verboo Code identity printed once before the Ink UI renders.
+ * Keep this compact: the terminal is a workspace, not a splash screen.
*/
import { VERBOO_ROUTER_URL, isVerbooMode } from '../constants/oauth.js'
@@ -19,89 +16,11 @@ const ESC = '\x1b['
const RESET = `${ESC}0m`
const DIM = `${ESC}2m`
-type RGB = [number, number, number]
const rgb = (r: number, g: number, b: number) => `${ESC}38;2;${r};${g};${b}m`
-function lerp(a: RGB, b: RGB, t: number): RGB {
- return [
- Math.round(a[0] + (b[0] - a[0]) * t),
- Math.round(a[1] + (b[1] - a[1]) * t),
- Math.round(a[2] + (b[2] - a[2]) * t),
- ]
-}
-
-function gradAt(stops: RGB[], t: number): RGB {
- const c = Math.max(0, Math.min(1, t))
- const s = c * (stops.length - 1)
- const i = Math.floor(s)
- if (i >= stops.length - 1) return stops[stops.length - 1]
- return lerp(stops[i], stops[i + 1], s - i)
-}
-
-function paintLine(text: string, stops: RGB[], lineT: number): string {
- let out = ''
- for (let i = 0; i < text.length; i++) {
- const t = text.length > 1 ? lineT * 0.5 + (i / (text.length - 1)) * 0.5 : lineT
- const [r, g, b] = gradAt(stops, t)
- out += `${rgb(r, g, b)}${text[i]}`
- }
- return out + RESET
-}
-
-// βββ Colors βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-
-// VERBOO-BRAND: purple gradient for the logo (was sunset orange)
-const SUNSET_GRAD: RGB[] = [
- [213, 142, 255], // light purple
- [193, 92, 255],
- [173, 52, 254], // brand #AD34FE
- [146, 1, 243],
- [110, 0, 200],
- [80, 0, 150],
-]
-
-const ACCENT: RGB = [173, 52, 254] // VERBOO-BRAND: brand purple
-const CREAM: RGB = [220, 200, 240] // VERBOO-BRAND: soft lavender
-const DIMCOL: RGB = [120, 100, 140] // VERBOO-BRAND: muted cool gray
-const BORDER: RGB = [80, 65, 100] // VERBOO-BRAND: dark cool gray
-
-// βββ Filled Block Text Logo βββββββββββββββββββββββββββββββββββββββββββββββββββ
-
-// VERBOO-BRAND: "VERBOO CODE" em uma linha, estilo rounded (cantos \u256d\u256e\u2570\u256f, tra\u00e7os \u2500)
-const LOGO_VERBOO_CODE = [
- ` \u2588\u2588\u256e \u2588\u2588\u256e\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u256e\u2588\u2588\u2588\u2588\u2588\u2588\u256e \u2588\u2588\u2588\u2588\u2588\u2588\u256e \u2588\u2588\u2588\u2588\u2588\u2588\u256e \u2588\u2588\u2588\u2588\u2588\u2588\u256e \u2588\u2588\u2588\u2588\u2588\u2588\u256e \u2588\u2588\u2588\u2588\u2588\u2588\u256e \u2588\u2588\u2588\u2588\u2588\u2588\u256e \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u256e`,
- ` \u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u256d\u2500\u2500\u2500\u2500\u256f\u2588\u2588\u256d\u2500\u2500\u2588\u2588\u256e\u2588\u2588\u256d\u2500\u2500\u2588\u2588\u256e\u2588\u2588\u256d\u2500\u2500\u2500\u2588\u2588\u256e\u2588\u2588\u256d\u2500\u2500\u2500\u2588\u2588\u256e \u2588\u2588\u256d\u2500\u2500\u2500\u2500\u256f\u2588\u2588\u256d\u2500\u2500\u2500\u2588\u2588\u256e\u2588\u2588\u256d\u2500\u2500\u2588\u2588\u256e\u2588\u2588\u256d\u2500\u2500\u2500\u2500\u256f`,
- ` \u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u2588\u2588\u2588\u256e \u2588\u2588\u2588\u2588\u2588\u2588\u256d\u256f\u2588\u2588\u2588\u2588\u2588\u2588\u256d\u256f\u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u2502 \u2588\u2588\u2502 \u2588\u2588\u2502 \u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u2588\u2588\u2588\u256e `,
- ` \u2570\u2588\u2588\u256e \u2588\u2588\u256d\u256f\u2588\u2588\u256d\u2500\u2500\u256f \u2588\u2588\u256d\u2500\u2500\u2588\u2588\u256e\u2588\u2588\u256d\u2500\u2500\u2588\u2588\u256e\u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u2502 \u2588\u2588\u2502 \u2588\u2588\u2502 \u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u256d\u2500\u2500\u256f `,
- ` \u2570\u2588\u2588\u2588\u2588\u256d\u256f \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u256e\u2588\u2588\u2502 \u2588\u2588\u2502\u2588\u2588\u2588\u2588\u2588\u2588\u256d\u256f\u2570\u2588\u2588\u2588\u2588\u2588\u2588\u256d\u256f\u2570\u2588\u2588\u2588\u2588\u2588\u2588\u256d\u256f \u2570\u2588\u2588\u2588\u2588\u2588\u2588\u256e\u2570\u2588\u2588\u2588\u2588\u2588\u2588\u256d\u256f\u2588\u2588\u2588\u2588\u2588\u2588\u256d\u256f\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u256e`,
- ` \u2570\u2500\u2500\u2500\u256f \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u256f\u2570\u2500\u256f \u2570\u2500\u256f\u2570\u2500\u2500\u2500\u2500\u2500\u256f \u2570\u2500\u2500\u2500\u2500\u2500\u256f \u2570\u2500\u2500\u2500\u2500\u2500\u256f \u2570\u2500\u2500\u2500\u2500\u2500\u256f \u2570\u2500\u2500\u2500\u2500\u2500\u256f \u2570\u2500\u2500\u2500\u2500\u2500\u256f \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u256f`,
-]
-
-// βββ Verboo ASCII Logo ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-
-const VERBOO_LOGO = [
- ` βββββββββ `,
- `βββββββββββββ`,
- `βββ βββββ βββ`,
- `βββββββββββββ`,
- `βββββββββββββ`,
- ` βββββββββββ `,
- `βββ βββββ βββ`,
-]
-
-// MΓ‘scara 1:1 com VERBOO_LOGO β 1 = bg roxo (bloco cheio), 0 = fg sΓ³ (meio-bloco)
-// Edite os 1/0 para escolher quais caracteres ficam totalmente preenchidos
-const VERBOO_LOGO_MASK = [
- ` 011111110 `,
- `0111111111110`,
- `1110111110111`,
- `1111011101111`,
- `1111100011111`,
- ` 11111111111 `,
- `110 01110 011`,
-]
-
-const STARTUP_LOGO_MIN_COLUMNS = 80
+const ACCENT = [173, 52, 254] as const
+const DIMCOL = [120, 100, 140] as const
+const STARTUP_DEFAULT_COLUMNS = 80
// βββ Provider detection βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
@@ -232,13 +151,6 @@ export function detectProvider(modelOverride?: string): { name: string; model: s
return { name: 'Verboo', model: resolvedModel, baseUrl, isLocal }
}
-// βββ Box drawing ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-
-function boxRow(content: string, width: number, rawLen: number): string {
- const pad = Math.max(0, width - 2 - rawLen)
- return `${rgb(...BORDER)}\u2502${RESET}${content}${' '.repeat(pad)}${rgb(...BORDER)}\u2502${RESET}`
-}
-
// βββ Main βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
function truncateStartupText(text: string, maxLength: number): string {
@@ -254,88 +166,30 @@ export function renderStartupScreen(
displayCwd: string,
columns: number,
): string {
- const out: string[] = []
+ const out: string[] = ['']
const bold = `${ESC}1m`
const PURPLE = rgb(...ACCENT)
- const PURPLE_FILL = `${rgb(...ACCENT)}${ESC}48;2;${ACCENT[0]};${ACCENT[1]};${ACCENT[2]}m`
- const SOFT = rgb(...CREAM)
const DIMP = `${DIM}${rgb(...DIMCOL)}`
const STATUS_C = p.isLocal ? rgb(130, 200, 140) : PURPLE
const statusLabel = p.isLocal ? 'local' : 'cloud'
- const LOGO_TEXT_PADDING = 2
-
- out.push('')
-
- if (columns < STARTUP_LOGO_MIN_COLUMNS) {
- const compactTextWidth = Math.max(1, columns - 6)
- const provider = truncateStartupText(`${p.name} \u00b7 ${p.model}`, compactTextWidth)
- const endpoint = truncateStartupText(p.baseUrl, compactTextWidth)
- const cwd = truncateStartupText(displayCwd, compactTextWidth)
-
- out.push(` ${PURPLE}\ud83d\udc7b${RESET} ${bold}${SOFT}Verboo Code${RESET} ${DIMP}v${version}${RESET}`)
- out.push(` ${DIMP}Tokens ilimitados \u00b7 Privacidade \u00b7 Velocidade${RESET}`)
- out.push(` ${DIMP}${provider}${RESET}`)
- out.push(` ${DIMP}${endpoint}${RESET}`)
- out.push(` ${DIMP}${cwd}${RESET}`)
- } else {
- const maxLogoWidth = Math.max(...VERBOO_LOGO.map(line => line.trimEnd().length))
- const rightTextWidth = Math.max(
- 1,
- columns - 2 - maxLogoWidth - LOGO_TEXT_PADDING,
- )
- const provider = truncateStartupText(`${p.name} \u00b7 ${p.model}`, rightTextWidth)
- const endpoint = truncateStartupText(p.baseUrl, rightTextWidth)
- const cwd = truncateStartupText(displayCwd, rightTextWidth)
- const rightCol = [
- ``,
- `${bold}${SOFT}Verboo Code${RESET} ${DIMP}v${version}${RESET}`,
- `${DIMP}Tokens ilimitados \u00b7 Privacidade \u00b7 Velocidade${RESET}`,
- `${DIMP}${provider}${RESET}`,
- `${DIMP}${endpoint}${RESET}`,
- `${DIMP}${cwd}${RESET}`,
- ``,
- ]
-
- const paintedLogo: { text: string; visualWidth: number }[] = []
- for (let i = 0; i < VERBOO_LOGO.length; i++) {
- const line = (VERBOO_LOGO[i] ?? '').trimEnd()
- const mask = VERBOO_LOGO_MASK[i] ?? ''
- let painted = ''
- for (let j = 0; j < line.length; j++) {
- const ch = line[j] ?? ''
- const isBlock = ch === '\u2580' || ch === '\u2584'
- if (isBlock && mask[j] === '1') {
- painted += `${PURPLE_FILL}${ch}${RESET}`
- } else if (isBlock) {
- painted += `${PURPLE}${ch}${RESET}`
- } else {
- painted += ch
- }
- }
- paintedLogo.push({ text: painted, visualWidth: line.length })
- }
-
- for (let i = 0; i < paintedLogo.length; i++) {
- const { text, visualWidth } = paintedLogo[i] ?? {
- text: '',
- visualWidth: 0,
- }
- const gap = ' '.repeat(
- Math.max(0, maxLogoWidth - visualWidth + LOGO_TEXT_PADDING),
- )
- out.push(` ${text}${gap}${rightCol[i] ?? ''}`)
- }
- }
-
+ const detailWidth = Math.max(1, columns - 8)
+ const providerAndModel = p.name === 'Verboo' ? p.model : `${p.name} Β· ${p.model}`
+ const model = truncateStartupText(providerAndModel, Math.max(1, detailWidth - statusLabel.length - 4))
+ const cwd = truncateStartupText(displayCwd, detailWidth)
+ const hint = truncateStartupText('Type a request, or use /help for commands', detailWidth)
+ const shownVersion = truncateStartupText(version, Math.max(1, columns - 24))
+
+ out.push(` π» ${bold}${PURPLE}Verboo Code${RESET} ${DIMP}v${shownVersion}${RESET}`)
+ out.push(` ${STATUS_C}β${RESET} ${DIMP}${model} Β· ${statusLabel}${RESET}`)
+ out.push(` ${DIMP}${cwd}${RESET}`)
out.push('')
- out.push(` ${STATUS_C}\u25cf${RESET} ${DIMP}${statusLabel}${RESET} ${DIMP}Ready \u2014 type ${RESET}${PURPLE}/help${RESET}${DIMP} to begin${RESET}`)
+ out.push(` ${DIMP}${hint}${RESET}`)
out.push('')
return `${out.join('\n')}\n`
}
-// VERBOO-BRAND: compact rounded header (replaces giant ASCII splash).
-// Layout inspired by the V2 logo style \u2014 logo + name + meta on the right.
+// VERBOO-BRAND: compact identity shared by every interactive startup.
export function printStartupScreen(modelOverride?: string): void {
// Skip in non-interactive / CI / print mode
if (process.env.CI || !process.stdout.isTTY) return
@@ -348,6 +202,6 @@ export function printStartupScreen(modelOverride?: string): void {
const displayCwd = home && cwd.startsWith(home) ? `~${cwd.slice(home.length)}` : cwd
const version = MACRO.DISPLAY_VERSION ?? MACRO.VERSION
- const columns = process.stdout.columns ?? STARTUP_LOGO_MIN_COLUMNS
+ const columns = process.stdout.columns ?? STARTUP_DEFAULT_COLUMNS
process.stdout.write(renderStartupScreen(p, version, displayCwd, columns))
}