diff --git a/packages/cli/src/gemini.tsx b/packages/cli/src/gemini.tsx
index 23990f6d..74091874 100644
--- a/packages/cli/src/gemini.tsx
+++ b/packages/cli/src/gemini.tsx
@@ -26,6 +26,7 @@ import { getUserStartupWarnings } from './utils/userStartupWarnings.js';
import { runNonInteractive } from './nonInteractiveCli.js';
import { loadExtensions, Extension } from './config/extension.js';
import { cleanupCheckpoints } from './utils/cleanup.js';
+import { getCliVersion } from './utils/version.js';
import {
ApprovalMode,
Config,
@@ -183,6 +184,7 @@ export async function main() {
// Render UI, passing necessary config values. Check that there is no command line question.
if (process.stdin.isTTY && input?.length === 0) {
+ const version = await getCliVersion();
setWindowTitle(basename(workspaceRoot), settings);
render(
@@ -190,6 +192,7 @@ export async function main() {
config={config}
settings={settings}
startupWarnings={startupWarnings}
+ version={version}
/>
,
{ exitOnCtrlC: false },
diff --git a/packages/cli/src/ui/App.test.tsx b/packages/cli/src/ui/App.test.tsx
index 32f13329..fffea64d 100644
--- a/packages/cli/src/ui/App.test.tsx
+++ b/packages/cli/src/ui/App.test.tsx
@@ -186,6 +186,7 @@ vi.mock('./components/Tips.js', () => ({
describe('App UI', () => {
let mockConfig: MockServerConfig;
let mockSettings: LoadedSettings;
+ let mockVersion: string;
let currentUnmount: (() => void) | undefined;
const createMockSettings = (
@@ -229,6 +230,7 @@ describe('App UI', () => {
cwd: '/tmp',
model: 'model',
}) as unknown as MockServerConfig;
+ mockVersion = '0.0.0-test';
// Ensure the getShowMemoryUsage mock function is specifically set up if not covered by constructor mock
if (!mockConfig.getShowMemoryUsage) {
@@ -258,6 +260,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -274,6 +277,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -293,6 +297,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -315,6 +320,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -334,6 +340,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -353,6 +360,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -372,6 +380,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -392,6 +401,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -404,6 +414,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -422,6 +433,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -440,6 +452,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -469,6 +482,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
@@ -483,6 +497,7 @@ describe('App UI', () => {
,
);
currentUnmount = unmount;
diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx
index 4e2c7242..519a4b53 100644
--- a/packages/cli/src/ui/App.tsx
+++ b/packages/cli/src/ui/App.tsx
@@ -84,6 +84,7 @@ interface AppProps {
config: Config;
settings: LoadedSettings;
startupWarnings?: string[];
+ version: string;
}
export const AppWrapper = (props: AppProps) => (
@@ -92,10 +93,11 @@ export const AppWrapper = (props: AppProps) => (
);
-const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
+const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
useBracketedPaste();
const [updateMessage, setUpdateMessage] = useState(null);
const { stdout } = useStdout();
+ const nightly = version.includes('nightly');
useEffect(() => {
checkForUpdates().then(setUpdateMessage);
@@ -315,7 +317,7 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
⚡ To continue accessing the ${currentModel} model today, consider using /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey`;
} else {
// Default fallback message for other cases (like consecutive 429s)
- message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
+ message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
⚡ To increase your limits, upgrade to a Gemini Code Assist Standard or Enterprise plan with higher limits at https://goo.gle/set-up-gemini-code-assist
⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
@@ -673,7 +675,11 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
key={staticKey}
items={[
-
+
{!settings.merged.hideTips && }
,
...history.map((h) => (
@@ -931,6 +937,7 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
config.getDebugMode() || config.getShowMemoryUsage()
}
promptTokenCount={sessionStats.lastPromptTokenCount}
+ nightly={nightly}
/>
diff --git a/packages/cli/src/ui/components/Footer.tsx b/packages/cli/src/ui/components/Footer.tsx
index 48f37ee8..95904cd9 100644
--- a/packages/cli/src/ui/components/Footer.tsx
+++ b/packages/cli/src/ui/components/Footer.tsx
@@ -10,6 +10,7 @@ import { Colors } from '../colors.js';
import { shortenPath, tildeifyPath, tokenLimit } from '@google/gemini-cli-core';
import { ConsoleSummaryDisplay } from './ConsoleSummaryDisplay.js';
import process from 'node:process';
+import Gradient from 'ink-gradient';
import { MemoryUsageDisplay } from './MemoryUsageDisplay.js';
interface FooterProps {
@@ -23,6 +24,7 @@ interface FooterProps {
showErrorDetails: boolean;
showMemoryUsage?: boolean;
promptTokenCount: number;
+ nightly: boolean;
}
export const Footer: React.FC = ({
@@ -36,6 +38,7 @@ export const Footer: React.FC = ({
showErrorDetails,
showMemoryUsage,
promptTokenCount,
+ nightly,
}) => {
const limit = tokenLimit(model);
const percentage = promptTokenCount / limit;
@@ -43,10 +46,19 @@ export const Footer: React.FC = ({
return (
-
- {shortenPath(tildeifyPath(targetDir), 70)}
- {branchName && ({branchName}*)}
-
+ {nightly ? (
+
+
+ {shortenPath(tildeifyPath(targetDir), 70)}
+ {branchName && ({branchName}*)}
+
+
+ ) : (
+
+ {shortenPath(tildeifyPath(targetDir), 70)}
+ {branchName && ({branchName}*)}
+
+ )}
{debugMode && (
{' ' + (debugMessage || '--debug')}
diff --git a/packages/cli/src/ui/components/Header.tsx b/packages/cli/src/ui/components/Header.tsx
index 375faf07..b99382e0 100644
--- a/packages/cli/src/ui/components/Header.tsx
+++ b/packages/cli/src/ui/components/Header.tsx
@@ -14,11 +14,15 @@ import { getAsciiArtWidth } from '../utils/textUtils.js';
interface HeaderProps {
customAsciiArt?: string; // For user-defined ASCII art
terminalWidth: number; // For responsive logo
+ version: string;
+ nightly: boolean;
}
export const Header: React.FC = ({
customAsciiArt,
terminalWidth,
+ version,
+ nightly,
}) => {
let displayTitle;
const widthOfLongLogo = getAsciiArtWidth(longAsciiLogo);
@@ -38,6 +42,7 @@ export const Header: React.FC = ({
alignItems="flex-start"
width={artWidth}
flexShrink={0}
+ flexDirection="column"
>
{Colors.GradientColors ? (
@@ -46,6 +51,13 @@ export const Header: React.FC = ({
) : (
{displayTitle}
)}
+ {nightly && (
+
+
+ v{version}
+
+
+ )}
);
};