Skip to content

feat(cli): add hostname to footer with smart visibility#25730

Open
NTaylorMullen wants to merge 1 commit intomainfrom
ntm/gh.25661.hostname
Open

feat(cli): add hostname to footer with smart visibility#25730
NTaylorMullen wants to merge 1 commit intomainfrom
ntm/gh.25661.hostname

Conversation

@NTaylorMullen
Copy link
Copy Markdown
Collaborator

@NTaylorMullen NTaylorMullen commented Apr 21, 2026

Summary

Add the system hostname to the persistent bottom status border of the Gemini CLI when running in remote or containerized environments.

Details

  • Smart Visibility: The hostname only appears when a remote or containerized environment is detected (SSH, Cloud Shell, Docker, Kubernetes). This provides context when managing multiple remote sessions without cluttering the UI for local-only users.
  • Short Hostnames: The hostname is truncated to its first segment (e.g., my-server instead of my-server.internal.domain.com) to preserve horizontal space.
  • Default Inclusion: Included in the default footer item list so it's discoverable out-of-the-box for users who need it.
  • Vim Mode Fix: Fixed a minor bug where vimEnabled was incorrectly destructured as enabled.

Related Issues

Fixes #25571

How to Validate

  1. Local Check: Run npm run start. Verify the hostname does NOT appear in the footer.
  2. Remote Simulation: Run SSH_TTY=/dev/pts/1 npm run start. Verify the hostname appears in the footer (usually between the sandbox and model name).
  3. Settings Dialog: Open Footer Settings (/settings -> UI -> Footer Items) and verify hostname is available for reordering or toggling.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
    • Linux

- Add hostname to footer ALL_ITEMS and DEFAULT_ORDER
- Implement smart visibility for hostname (only show when remote/container)
- Shorten hostname to first segment to save space
- Fix vimEnabled destructuring in Footer.tsx

Fixes #25661
@NTaylorMullen NTaylorMullen requested a review from a team as a code owner April 21, 2026 03:52
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the Gemini CLI user interface by introducing a context-aware hostname display in the footer. By detecting remote or containerized execution environments, the CLI now provides helpful infrastructure context to users working across multiple sessions while maintaining a clean UI for local users. Additionally, minor bug fixes and configuration updates were included to ensure the new feature is discoverable and correctly integrated into the existing settings framework.

Highlights

  • Hostname Display: Added the system hostname to the CLI footer, which is intelligently displayed only when running in remote or containerized environments.
  • Smart Environment Detection: Implemented logic to detect SSH, Cloud Shell, Docker, and Kubernetes environments to toggle the visibility of the hostname.
  • UI Improvements: Truncated hostnames to their first segment to optimize space and fixed a destructuring bug in the Vim mode configuration.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds a 'hostname' item to the CLI footer, displayed when the environment is remote or containerized. The update includes configuration changes, logic to detect remote sessions via environment variables and Docker presence, and corresponding unit tests. Feedback was provided to optimize performance by moving the synchronous filesystem check for Docker detection to the module level, preventing redundant I/O operations during component re-renders.

} from '../../config/footerItems.js';
import { isDevelopment } from '../../utils/installationInfo.js';

const SYSTEM_HOSTNAME = hostname().split('.')[0];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Docker environment check should be performed once at the module level to avoid repeated synchronous I/O during component renders. Synchronous filesystem operations like fs.existsSync inside a React component's render cycle are a performance anti-pattern, as they execute on every re-render.

Suggested change
const SYSTEM_HOSTNAME = hostname().split('.')[0];
const SYSTEM_HOSTNAME = hostname().split('.')[0];
const IS_DOCKER = process.platform === 'linux' && fs.existsSync('/.dockerenv');

Comment on lines +187 to +194
const isRemote =
process.env['SSH_TTY'] ||
process.env['SSH_CONNECTION'] ||
process.env['SSH_CLIENT'] ||
process.env['CLOUD_SHELL'] === 'true' ||
process.env['EDITOR_IN_CLOUD_SHELL'] === 'true' ||
process.env['KUBERNETES_SERVICE_HOST'] ||
(process.platform === 'linux' && fs.existsSync('/.dockerenv'));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

As noted above, the isRemote check should use a module-level constant for the Docker check to avoid repeated blocking I/O. The environment variable checks are kept inside the component to ensure they remain testable with vi.stubEnv.

Suggested change
const isRemote =
process.env['SSH_TTY'] ||
process.env['SSH_CONNECTION'] ||
process.env['SSH_CLIENT'] ||
process.env['CLOUD_SHELL'] === 'true' ||
process.env['EDITOR_IN_CLOUD_SHELL'] === 'true' ||
process.env['KUBERNETES_SERVICE_HOST'] ||
(process.platform === 'linux' && fs.existsSync('/.dockerenv'));
const isRemote = !!(
process.env['SSH_TTY'] ||
process.env['SSH_CONNECTION'] ||
process.env['SSH_CLIENT'] ||
process.env['CLOUD_SHELL'] === 'true' ||
process.env['EDITOR_IN_CLOUD_SHELL'] === 'true' ||
process.env['KUBERNETES_SERVICE_HOST'] ||
IS_DOCKER
);

@github-actions
Copy link
Copy Markdown

Size Change: +912 B (0%)

Total Size: 33.7 MB

Filename Size Change
./bundle/chunk-7HZ62EWV.js 0 B -14.5 MB (removed) 🏆
./bundle/chunk-7JYX7OYE.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-7LSIJV5T.js 0 B -3.8 kB (removed) 🏆
./bundle/chunk-QOIPE2QP.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-TFETZB54.js 0 B -674 kB (removed) 🏆
./bundle/chunk-USRW35AA.js 0 B -2.72 MB (removed) 🏆
./bundle/core-XRKWYEBZ.js 0 B -46.7 kB (removed) 🏆
./bundle/devtoolsService-JM7UV5K7.js 0 B -28.4 kB (removed) 🏆
./bundle/gemini-HBHBH6VI.js 0 B -576 kB (removed) 🏆
./bundle/interactiveCli-VGZMS7IN.js 0 B -1.3 MB (removed) 🏆
./bundle/liteRtServerManager-56MHLN2Q.js 0 B -2.08 kB (removed) 🏆
./bundle/oauth2-provider-UE6YCM4Y.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-65HUZXRG.js 674 kB +674 kB (new file) 🆕
./bundle/chunk-GSE53DEI.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-IEFNLBUI.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/chunk-LTOJG5AP.js 2.72 MB +2.72 MB (new file) 🆕
./bundle/chunk-PMGLNJPI.js 14.5 MB +14.5 MB (new file) 🆕
./bundle/chunk-UFXJ33JI.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/core-OBZZVD5Z.js 46.7 kB +46.7 kB (new file) 🆕
./bundle/devtoolsService-4EUSLZQ6.js 28.4 kB +28.4 kB (new file) 🆕
./bundle/gemini-VRDKSDL5.js 576 kB +576 kB (new file) 🆕
./bundle/interactiveCli-TEUC6LUX.js 1.3 MB +1.3 MB (new file) 🆕
./bundle/liteRtServerManager-LD4QUQUM.js 2.08 kB +2.08 kB (new file) 🆕
./bundle/oauth2-provider-NUBRRVDP.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/chunk-YIPDXML5.js 1.97 MB 0 B
./bundle/cleanup-GLDYQJA4.js 0 B -932 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 4.97 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-NXEEFR74.js 980 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-UAYHAXS3.js 0 B -622 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-PUWST4RN.js 932 B +932 B (new file) 🆕
./bundle/start-SPYZQV2C.js 622 B +622 B (new file) 🆕

compressed-size-action

Copy link
Copy Markdown

@nidhishgajjar nidhishgajjar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of PR #25730: feat(cli): add hostname to footer with smart visibility

Summary

This PR adds system hostname display to the Gemini CLI footer with intelligent visibility - only showing when running in remote or containerized environments (SSH, Cloud Shell, Docker, Kubernetes).

Changes Analysis

1. packages/cli/src/config/footerItems.ts

Added hostname configuration:

  • Added to ALL_ITEMS with id hostname, header host, and clear description
  • Added to DEFAULT_ORDER between sandbox and model-name (logical placement)
  • Added to deriveItemsFromLegacySettings for backward compatibility

Placement is appropriate - hostname appears after sandbox info but before model name, making it easy to spot in remote sessions.

2. packages/cli/src/ui/components/Footer.test.tsx

Comprehensive test coverage:

  • Test 1: Verifies hostname renders when remote (SSH_TTY set)
  • Test 2: Verifies hostname does NOT render when not remote (clean env)

Test quality:

  • Uses vi.stubEnv for environment variable mocking
  • Tests both positive and negative scenarios
  • Properly cleans up with unmount()
  • Uses allowEmpty: true for the negative test

3. packages/cli/src/ui/components/Footer.tsx

Hostname extraction:

const SYSTEM_HOSTNAME = hostname().split(".")[0];
  • Truncates to first segment (e.g., my-server instead of my-server.internal.domain.com)
  • Preserves horizontal space in the footer
  • Good UX decision

Remote detection:

const isRemote =
  process.env["SSH_TTY"] ||
  process.env["SSH_CONNECTION"] ||
  process.env["SSH_CLIENT"] ||
  process.env["CLOUD_SHELL"] === "true" ||
  process.env["EDITOR_IN_CLOUD_SHELL"] === "true" ||
  process.env["KUBERNETES_SERVICE_HOST"] ||
  (process.platform === "linux" && fs.existsSync("/.dockerenv"));

Comprehensive coverage:

  • SSH: SSH_TTY, SSH_CONNECTION, SSH_CLIENT
  • Google Cloud Shell: CLOUD_SHELL, EDITOR_IN_CLOUD_SHELL
  • Kubernetes: KUBERNETES_SERVICE_HOST
  • Docker: Checks for /.dockerenv on Linux

Smart visibility logic:

case "hostname": {
  if (isRemote && SYSTEM_HOSTNAME) {
    addCol(
      id,
      header,
      () => <Text color={itemColor}>{SYSTEM_HOSTNAME}</Text>,
      SYSTEM_HOSTNAME.length,
    );
  }
  break;
}
  • Only renders when both conditions are met
  • Prevents display for local sessions
  • Handles empty hostname gracefully

Bug fix (bonus):

// Before:
const { vimEnabled, vimMode } = useVimMode();

// After:
const { vimMode, vimEnabled } = useVimMode();
  • Fixed destructuring order
  • This was likely causing issues with vim mode detection

Strengths

  1. Smart visibility: Only shows hostname when relevant (remote/container)
  2. Comprehensive detection: Covers SSH, Cloud Shell, Kubernetes, Docker
  3. Good UX: Truncated hostname saves space
  4. Well-tested: Both positive and negative scenarios covered
  5. Bug fix included: Fixed vim mode destructuring
  6. Backward compatible: Added to legacy settings migration
  7. Good documentation: Clear PR description with validation steps

Minor Suggestions

1. Type Safety

The isRemote check relies on truthy values, which could be more explicit:

const isRemote =
  !!process.env["SSH_TTY"] ||
  !!process.env["SSH_CONNECTION"] ||
  !!process.env["SSH_CLIENT"] ||
  process.env["CLOUD_SHELL"] === "true" ||
  process.env["EDITOR_IN_CLOUD_SHELL"] === "true" ||
  !!process.env["KUBERNETES_SERVICE_HOST"] ||
  (process.platform === "linux" && fs.existsSync("/.dockerenv"));

However, the current implementation works fine since these env vars are either set or not set.

2. Docker Detection on non-Linux

The Docker detection only works on Linux:

(process.platform === "linux" && fs.existsSync("/.dockerenv"))

Consider expanding to other platforms:

const isDocker =
  (process.platform === "linux" && fs.existsSync("/.dockerenv")) ||
  (process.platform === "darwin" && /* macOS Docker detection */) ||
  (process.platform === "win32" && /* Windows Docker detection */);

However, this may be acceptable if Docker is primarily used on Linux for this use case.

3. Hostname Truncation Edge Case

The hostname truncation could result in an empty string:

const SYSTEM_HOSTNAME = hostname().split(".")[0];

If hostname() returns .example.com, this would result in an empty string. Consider:

const SYSTEM_HOSTNAME = hostname().split(".")[0] || hostname();

However, this is unlikely in practice.

4. Platform-Specific Tests

The pre-merge checklist shows:

  • MacOS (npm run, npx)
  • Windows
  • Linux
  • Docker/Podman/Seatbelt

Consider adding tests for:

  • Windows remote detection
  • Docker environment detection
  • Cloud Shell environment

Potential Concerns

1. False Positives

The isRemote detection could have false positives:

  • SSH_TTY might be set in some local development setups
  • KUBERNETES_SERVICE_HOST could be set in local Kubernetes clusters

However, showing the hostname in these cases is probably acceptable - it provides context without being harmful.

2. Performance

The fs.existsSync("/.dockerenv") check is synchronous. For better performance, consider:

import { existsSync } from "node:fs";
// ...
const isDocker = process.platform === "linux" && existsSync("/.dockerenv");

However, this is called once per render, and the performance impact is negligible.

Approval Criteria

I would approve this PR if:

  • Changes are well-structured and maintainable ✅
  • Tests cover the new behavior ✅
  • Smart visibility logic is comprehensive ✅
  • Bug fix included (vim mode destructuring) ✅
  • Good documentation ✅
  • Platform-specific tests completed (from pre-merge checklist)

Overall Assessment

Excellent implementation with smart visibility
Comprehensive remote/container detection
Well-tested with both scenarios
Includes bug fix (vim mode destructuring)
Good UX decisions (truncated hostname)
⚠️ Consider platform-specific testing

This is a well-implemented feature that addresses a real user need (identifying remote sessions) without cluttering the UI for local users. The smart visibility logic is comprehensive and the tests are thorough.

Recommendation: Approve (pending completion of pre-merge checklist items)

@gemini-cli gemini-cli Bot added area/core Issues related to User Interface, OS Support, Core Functionality help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! labels Apr 21, 2026
@M-DEV-1
Copy link
Copy Markdown

M-DEV-1 commented Apr 21, 2026

I think you meant this PR? @jackwotherspoon

#25637

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add machine hostname to CLI interface

3 participants