From a5ec8e370cf2e7ffa315068cfafc8d8ad3c5c529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Meichelb=C3=B6ck=20=5Biot=20rocket=5D?= Date: Sat, 30 Aug 2025 16:36:06 +0200 Subject: [PATCH] Add gemini-cli feature --- .github/workflows/test.yaml | 2 + CLAUDE.md | 1 + README.md | 1 + src/gemini-cli/NOTES.md | 31 ++++++++++ src/gemini-cli/README.md | 60 +++++++++++++++++++ src/gemini-cli/devcontainer-feature.json | 18 ++++++ src/gemini-cli/install.sh | 44 ++++++++++++++ .../gemini-cli/gemini_cli_with_custom_user.sh | 21 +++++++ .../gemini_cli_with_node_feature.sh | 20 +++++++ test/gemini-cli/gemini_cli_with_node_image.sh | 20 +++++++ test/gemini-cli/scenarios.json | 27 +++++++++ 11 files changed, 245 insertions(+) create mode 100644 src/gemini-cli/NOTES.md create mode 100644 src/gemini-cli/README.md create mode 100644 src/gemini-cli/devcontainer-feature.json create mode 100755 src/gemini-cli/install.sh create mode 100755 test/gemini-cli/gemini_cli_with_custom_user.sh create mode 100755 test/gemini-cli/gemini_cli_with_node_feature.sh create mode 100755 test/gemini-cli/gemini_cli_with_node_image.sh create mode 100644 test/gemini-cli/scenarios.json diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b9e03a1..c5294dc 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -17,6 +17,7 @@ jobs: - chrome - codex - color + - gemini-cli - hello - imagemagick - mc @@ -46,6 +47,7 @@ jobs: - claude-code - codex - color + - gemini-cli - hello - imagemagick - mc diff --git a/CLAUDE.md b/CLAUDE.md index 4066379..1b0912f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,6 +33,7 @@ This is Tobias Maier's Dev Container Features collection - a repository for crea - `chrome` - Google Chrome installation - `claude-code` - Claude Code CLI for AI-powered development assistance - `codex` - OpenAI Codex CLI for local AI-powered coding assistance +- `gemini-cli` - Google Gemini CLI for AI-powered development assistance - `imagemagick` - ImageMagick image processing tools - `mc` - MinIO Client for object storage - `mcp-language-server` - MCP Language Server for semantic code navigation diff --git a/README.md b/README.md index 9ec71e6..6a2d3b9 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ A collection of custom [Dev Container Features](https://containers.dev/implement | [chrome](https://github.com/tmaier/devcontainer-features/tree/main/src/chrome) | Google Chrome with container-optimized wrapper script | `ghcr.io/tmaier/devcontainer-features/chrome` | | [claude-code](https://github.com/tmaier/devcontainer-features/tree/main/src/claude-code) | Claude Code CLI for AI-powered development assistance | `ghcr.io/tmaier/devcontainer-features/claude-code` | | [codex](https://github.com/tmaier/devcontainer-features/tree/main/src/codex) | OpenAI Codex CLI for local AI-powered coding assistance | `ghcr.io/tmaier/devcontainer-features/codex` | +| [gemini-cli](https://github.com/tmaier/devcontainer-features/tree/main/src/gemini-cli) | Google Gemini CLI for AI-powered development assistance | `ghcr.io/tmaier/devcontainer-features/gemini-cli` | | [imagemagick](https://github.com/tmaier/devcontainer-features/tree/main/src/imagemagick) | ImageMagick image processing library with PDF support | `ghcr.io/tmaier/devcontainer-features/imagemagick` | | [mc](https://github.com/tmaier/devcontainer-features/tree/main/src/mc) | MinIO Client for object storage operations | `ghcr.io/tmaier/devcontainer-features/mc` | | [mcp-language-server](https://github.com/tmaier/devcontainer-features/tree/main/src/mcp-language-server) | MCP Language Server for semantic code navigation | `ghcr.io/tmaier/devcontainer-features/mcp-language-server` | diff --git a/src/gemini-cli/NOTES.md b/src/gemini-cli/NOTES.md new file mode 100644 index 0000000..7cbf110 --- /dev/null +++ b/src/gemini-cli/NOTES.md @@ -0,0 +1,31 @@ +# Gemini CLI Feature + +This feature installs [Gemini CLI](https://github.com/google-gemini/gemini-cli), Google's official CLI for AI-powered development assistance using Gemini models. + +## Requirements + +- Node.js + +## Manual config for `devcontainer.json` + +Mount the local `~/.gemini/` directory into the Dev Container. +Add the following mount to the `devcontainer.json` file. +Replace `vscode` with the actual name of your user (see `remoteUser` property) + +```json + "mounts": [ + { + "source": "${localEnv:HOME}/.gemini", + "target": "/home/vscode/.gemini", + "type": "bind" + } + ], +``` + +## Usage + +After installation, run `gemini` in your project directory to get started. + +You'll need to authenticate with Google AI Studio to access the Gemini API. + +For detailed documentation, see the [Gemini CLI documentation](https://github.com/google-gemini/gemini-cli). \ No newline at end of file diff --git a/src/gemini-cli/README.md b/src/gemini-cli/README.md new file mode 100644 index 0000000..b7c239c --- /dev/null +++ b/src/gemini-cli/README.md @@ -0,0 +1,60 @@ +# Gemini CLI (gemini-cli) + +Installs Google Gemini CLI for AI-powered development assistance + +## Example Usage + +```json +"features": { + "ghcr.io/tmaier/devcontainer-features/gemini-cli:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| + + +## Customizations + +### VS Code Extensions + +- `Google.gemini-cli-vscode-ide-companion` + +# Gemini CLI Feature + +This feature installs [Gemini CLI](https://github.com/google-gemini/gemini-cli), Google's official CLI for AI-powered development assistance using Gemini models. + +## Requirements + +- Node.js + +## Manual config for `devcontainer.json` + +Mount the local `~/.gemini/` directory into the Dev Container. +Add the following mount to the `devcontainer.json` file. +Replace `vscode` with the actual name of your user (see `remoteUser` property) + +```json + "mounts": [ + { + "source": "${localEnv:HOME}/.gemini", + "target": "/home/vscode/.gemini", + "type": "bind" + } + ], +``` + +## Usage + +After installation, run `gemini` in your project directory to get started. + +You'll need to authenticate with Google AI Studio to access the Gemini API. + +For detailed documentation, see the [Gemini CLI documentation](https://github.com/google-gemini/gemini-cli). + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/tmaier/devcontainer-features/blob/main/src/gemini-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ \ No newline at end of file diff --git a/src/gemini-cli/devcontainer-feature.json b/src/gemini-cli/devcontainer-feature.json new file mode 100644 index 0000000..39f23bc --- /dev/null +++ b/src/gemini-cli/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "gemini-cli", + "version": "1.0.0", + "name": "Gemini CLI", + "description": "Installs Google Gemini CLI for AI-powered development assistance", + "options": {}, + "installsAfter": [ + "ghcr.io/devcontainers/features/node" + ], + "customizations": { + "vscode": { + "extensions": [ + "Google.gemini-cli-vscode-ide-companion" + ] + } + }, + "postStartCommand": "if command -v gemini &>/dev/null; then gemini --version || true; fi" +} \ No newline at end of file diff --git a/src/gemini-cli/install.sh b/src/gemini-cli/install.sh new file mode 100755 index 0000000..6773b8e --- /dev/null +++ b/src/gemini-cli/install.sh @@ -0,0 +1,44 @@ +#!/bin/bash +set -e + +echo "Installing Gemini CLI..." + +# Check if Node.js is available +if ! command -v node &> /dev/null; then + echo "Error: Node.js is required but not found. Please ensure the Node.js feature is installed." + exit 1 +fi + +# Check Node.js version (requires 18+) +NODE_VERSION=$(node --version | sed 's/v//') +MAJOR_VERSION=$(echo $NODE_VERSION | cut -d. -f1) + +if [ "$MAJOR_VERSION" -lt 18 ]; then + echo "Error: Node.js 18+ is required, but found version $NODE_VERSION" + exit 1 +fi + +# Check if npm is available +if ! command -v npm &> /dev/null; then + echo "Error: npm is required but not found." + exit 1 +fi + +# Install Gemini CLI - prefer remote user installation if available +if [ -n "$_REMOTE_USER" ] && [ "$_REMOTE_USER" != "root" ]; then + echo "Installing Gemini CLI as user: $_REMOTE_USER" + NPM_PATH=$(which npm) + BIN_DIR=$(dirname "$NPM_PATH") + su "$_REMOTE_USER" -c "PATH=$BIN_DIR:\$PATH $NPM_PATH install -g @google/gemini-cli" +else + echo "Installing Gemini CLI globally as root" + npm install -g @google/gemini-cli +fi + +# Verify installation +if ! command -v gemini &> /dev/null; then + echo "Error: Gemini CLI installation failed" + exit 1 +fi + +echo "Gemini CLI installed successfully!" \ No newline at end of file diff --git a/test/gemini-cli/gemini_cli_with_custom_user.sh b/test/gemini-cli/gemini_cli_with_custom_user.sh new file mode 100755 index 0000000..fb02e4d --- /dev/null +++ b/test/gemini-cli/gemini_cli_with_custom_user.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# This test file will be executed against the 'gemini_cli_with_custom_user' scenario +# to verify that Gemini CLI is properly installed with a custom user setup. + +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +# Feature-specific tests - simple smoke test +# The 'check' command comes from the dev-container-features-test-lib. +check "node is available" which node +check "npm is available" which npm +check "gemini command available" which gemini +check "gemini shows version" bash -c "gemini --version" +check "current user is vscode" bash -c "[ \"\$(whoami)\" = \"vscode\" ]" + +# Report results +# If any of the checks above exited with a non-zero exit code, the test will fail. +reportResults \ No newline at end of file diff --git a/test/gemini-cli/gemini_cli_with_node_feature.sh b/test/gemini-cli/gemini_cli_with_node_feature.sh new file mode 100755 index 0000000..35e71a2 --- /dev/null +++ b/test/gemini-cli/gemini_cli_with_node_feature.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# This test file will be executed against the 'gemini_cli_with_node_feature' scenario +# to verify that Gemini CLI is properly installed with Node.js feature dependency. + +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +# Feature-specific tests - simple smoke test +# The 'check' command comes from the dev-container-features-test-lib. +check "node is available" which node +check "npm is available" which npm +check "gemini command available" which gemini +check "gemini shows version" bash -c "gemini --version" + +# Report results +# If any of the checks above exited with a non-zero exit code, the test will fail. +reportResults \ No newline at end of file diff --git a/test/gemini-cli/gemini_cli_with_node_image.sh b/test/gemini-cli/gemini_cli_with_node_image.sh new file mode 100755 index 0000000..599bd8b --- /dev/null +++ b/test/gemini-cli/gemini_cli_with_node_image.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# This test file will be executed against the 'gemini_cli_with_node_image' scenario +# to verify that Gemini CLI is properly installed on a Node.js base image. + +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +# Feature-specific tests - simple smoke test +# The 'check' command comes from the dev-container-features-test-lib. +check "node is available" which node +check "npm is available" which npm +check "gemini command available" which gemini +check "gemini shows version" bash -c "gemini --version" + +# Report results +# If any of the checks above exited with a non-zero exit code, the test will fail. +reportResults \ No newline at end of file diff --git a/test/gemini-cli/scenarios.json b/test/gemini-cli/scenarios.json new file mode 100644 index 0000000..5996699 --- /dev/null +++ b/test/gemini-cli/scenarios.json @@ -0,0 +1,27 @@ +{ + "gemini_cli_with_node_feature": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "lts" + }, + "gemini-cli": {} + } + }, + "gemini_cli_with_node_image": { + "image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bullseye", + "features": { + "gemini-cli": {} + } + }, + "gemini_cli_with_custom_user": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "remoteUser": "vscode", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "lts" + }, + "gemini-cli": {} + } + } +} \ No newline at end of file