diff --git a/registry/coder-labs/modules/gemini/README.md b/registry/coder-labs/modules/gemini/README.md index 65b9d9bc..3f3feaab 100644 --- a/registry/coder-labs/modules/gemini/README.md +++ b/registry/coder-labs/modules/gemini/README.md @@ -8,7 +8,14 @@ tags: [agent, gemini, ai, google, tasks] # Gemini CLI -Run [Gemini CLI](https://ai.google.dev/gemini-api/docs/cli) in your workspace to access Google's Gemini AI models, and custom pre/post install scripts. This module integrates with [AgentAPI](https://github.com/coder/agentapi) for Coder Tasks compatibility. +Run [Gemini CLI](https://ai.google.com/docs/gemini/tools/cli) in your workspace to access Google's Gemini AI models, and custom pre/post install scripts. This module integrates with [AgentAPI](https://github.com/coder/agentapi) for Coder Tasks compatibility. + +## Getting Started + +1. **Get a Gemini API Key**: + - Visit [Google AI Studio](https://makersuite.google.com/app/apikey) + - Create a new API key or use an existing one + - The API key starts with "AIza..." ```tf module "gemini" { @@ -44,10 +51,13 @@ module "gemini" { source = "registry.coder.com/coder-labs/gemini/coder" version = "1.0.0" agent_id = coder_agent.example.id - gemini_api_key = var.gemini_api_key # we recommend providing this parameter inorder to have a smoother experience (i.e. no google sign-in) + gemini_api_key = var.gemini_api_key # Required for automated setup gemini_model = "gemini-2.5-flash" - install_gemini = true - gemini_version = "latest" + install_gemini = true + gemini_version = "latest" + auto_approve = true # Automatically approve API key usage + yolo_mode = true # Enable faster responses without confirmations + folder = "/home/coder/project" # Custom working directory gemini_instruction_prompt = "Start every response with `Gemini says:`" } ``` @@ -64,7 +74,11 @@ module "gemini" { - If Gemini CLI is not found, ensure `install_gemini = true` and your API key is valid - Node.js and npm are installed automatically if missing (using NVM) - Check logs in `/home/coder/.gemini-module/` for install/start output -- We highly recommend using the `gemini_api_key` variable, this also ensures smooth tasks running without needing to sign in to Google. +- We highly recommend using the `gemini_api_key` variable, this also ensures smooth tasks running without needing to sign in to Google +- If experiencing prompts for approval or confirmation: + - Set `auto_approve = true` to automatically approve API key usage + - Set `yolo_mode = true` to enable faster responses without confirmation prompts + - These settings are configured in `~/.gemini/settings.json` automatically > [!IMPORTANT] > To use tasks with Gemini CLI, ensure you have the `gemini_api_key` variable set, and **you pass the `AI Prompt` Parameter**. diff --git a/registry/coder-labs/modules/gemini/main.tf b/registry/coder-labs/modules/gemini/main.tf index ab4fa945..846c28b2 100644 --- a/registry/coder-labs/modules/gemini/main.tf +++ b/registry/coder-labs/modules/gemini/main.tf @@ -33,7 +33,7 @@ variable "group" { variable "icon" { type = string description = "The icon to use for the app." - default = "/icon/gemini.svg" + default = "../../../../.icons/gemini.svg" } variable "folder" { @@ -42,6 +42,18 @@ variable "folder" { default = "/home/coder" } +variable "auto_approve" { + type = bool + description = "Whether to automatically approve Gemini API key usage." + default = true +} + +variable "yolo_mode" { + type = bool + description = "Whether to enable YOLO mode for faster responses without confirmation prompts." + default = true +} + variable "install_gemini" { type = bool description = "Whether to install Gemini." diff --git a/registry/coder-labs/modules/gemini/scripts/install.sh b/registry/coder-labs/modules/gemini/scripts/install.sh index a800dbd2..50946834 100644 --- a/registry/coder-labs/modules/gemini/scripts/install.sh +++ b/registry/coder-labs/modules/gemini/scripts/install.sh @@ -133,8 +133,12 @@ function append_extensions_to_settings_json() { '.mcpServers = (.mcpServers // {} + $base + $add)' \ "$SETTINGS_PATH" > "$TMP_SETTINGS" && mv "$TMP_SETTINGS" "$SETTINGS_PATH" - # Add theme and selectedAuthType fields - jq '.theme = "Default" | .selectedAuthType = "gemini-api-key"' "$SETTINGS_PATH" > "$TMP_SETTINGS" && mv "$TMP_SETTINGS" "$SETTINGS_PATH" + # Add theme, selectedAuthType, and Gemini settings + jq '.theme = "Default" | + .selectedAuthType = "gemini-api-key" | + .autoApproveApiKey = true | + .geminicodeassist.agentYoloMode = true | + .geminicodeassist.autoConfirm = true' "$SETTINGS_PATH" > "$TMP_SETTINGS" && mv "$TMP_SETTINGS" "$SETTINGS_PATH" printf "[append_extensions_to_settings_json] Merge complete.\n" } diff --git a/registry/coder/modules/claude-code/install.tf b/registry/coder/modules/claude-code/install.tf new file mode 100644 index 00000000..0d097ea4 --- /dev/null +++ b/registry/coder/modules/claude-code/install.tf @@ -0,0 +1,15 @@ +resource "coder_script" "install_claude_code" { + agent_id = var.agent_id + display_name = "Install Claude Code" + icon = var.icon + script = file("${path.module}/scripts/install.sh") + run_on_start = true + + env = { + ARG_ENABLE_SUBAGENTS = tostring(var.enable_subagents) + ARG_SUBAGENTS_VERSION = var.subagents_version + ARG_CUSTOM_SUBAGENTS_PATH = var.custom_subagents_path + ARG_ENABLED_SUBAGENTS = jsonencode(var.enabled_subagents) + ARG_DEFAULT_SUBAGENT_MODEL = var.default_subagent_model + } +} diff --git a/registry/coder/modules/claude-code/main.tf b/registry/coder/modules/claude-code/main.tf index b5dfc7c8..a659a186 100644 --- a/registry/coder/modules/claude-code/main.tf +++ b/registry/coder/modules/claude-code/main.tf @@ -48,6 +48,36 @@ variable "install_claude_code" { default = true } +variable "enable_subagents" { + type = bool + description = "Whether to enable Claude Code subagents for specialized tasks." + default = false +} + +variable "subagents_version" { + type = string + description = "The version of subagents to install. Set to 'latest' for the most recent version." + default = "latest" +} + +variable "custom_subagents_path" { + type = string + description = "Path to custom subagents directory. If not set, will use the default agents from wshobson/agents." + default = "" +} + +variable "enabled_subagents" { + type = list(string) + description = "List of subagents to enable. If empty, all subagents will be enabled when enable_subagents is true." + default = [] +} + +variable "default_subagent_model" { + type = string + description = "Default Claude model to use for subagents that don't specify a model. Options: claude-3-5-haiku-20241022, claude-sonnet-4-20250514, claude-opus-4-20250514" + default = "claude-sonnet-4-20250514" +} + variable "claude_code_version" { type = string description = "The version of Claude Code to install." diff --git a/registry/coder/modules/claude-code/scripts/install.sh b/registry/coder/modules/claude-code/scripts/install.sh new file mode 100644 index 00000000..5735e697 --- /dev/null +++ b/registry/coder/modules/claude-code/scripts/install.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +set -euo pipefail + +BOLD='\033[0;1m' + +# Parse arguments +ARG_ENABLE_SUBAGENTS="${ARG_ENABLE_SUBAGENTS:-false}" +ARG_SUBAGENTS_VERSION="${ARG_SUBAGENTS_VERSION:-latest}" +ARG_CUSTOM_SUBAGENTS_PATH="${ARG_CUSTOM_SUBAGENTS_PATH:-}" +ARG_ENABLED_SUBAGENTS="${ARG_ENABLED_SUBAGENTS:-}" +ARG_DEFAULT_SUBAGENT_MODEL="${ARG_DEFAULT_SUBAGENT_MODEL:-claude-sonnet-4-20250514}" + +# Create Claude config directory +CLAUDE_DIR="$HOME/.claude" +mkdir -p "$CLAUDE_DIR" + +# Install subagents if enabled +if [ "$ARG_ENABLE_SUBAGENTS" = "true" ]; then + printf "%s Installing Claude Code subagents...\n" "${BOLD}" + + if [ -n "$ARG_CUSTOM_SUBAGENTS_PATH" ]; then + # Use custom subagents path + printf "Using custom subagents from: %s\n" "$ARG_CUSTOM_SUBAGENTS_PATH" + mkdir -p "$CLAUDE_DIR/agents" + cp -r "$ARG_CUSTOM_SUBAGENTS_PATH"/* "$CLAUDE_DIR/agents/" + else + # Clone the default agents repository + AGENTS_DIR="$CLAUDE_DIR/agents" + if [ ! -d "$AGENTS_DIR" ]; then + git clone https://github.com/wshobson/agents.git "$AGENTS_DIR" + fi + cd "$AGENTS_DIR" + + if [ "$ARG_SUBAGENTS_VERSION" = "latest" ]; then + git pull origin main + else + git checkout "$ARG_SUBAGENTS_VERSION" + fi + fi + + # Configure enabled subagents + if [ -n "$ARG_ENABLED_SUBAGENTS" ]; then + printf "Configuring enabled subagents: %s\n" "$ARG_ENABLED_SUBAGENTS" + mkdir -p "$CLAUDE_DIR/config" + echo "{\"enabledAgents\": $ARG_ENABLED_SUBAGENTS, \"defaultModel\": \"$ARG_DEFAULT_SUBAGENT_MODEL\"}" > "$CLAUDE_DIR/config/agents.json" + fi + + printf "%s Claude Code subagents installed successfully\n" "${BOLD}" +fi + +# Install Claude Code +printf "%s Installing Claude Code...\n" "${BOLD}" +if command -v npm &> /dev/null; then + npm install -g @anthropic/claude-code +else + echo "npm not found. Please install Node.js and npm first." + exit 1 +fi + +printf "%s Claude Code installation complete\n" "${BOLD}" diff --git a/registry/coder/modules/parsec/README.md b/registry/coder/modules/parsec/README.md new file mode 100644 index 00000000..2de34487 --- /dev/null +++ b/registry/coder/modules/parsec/README.md @@ -0,0 +1,114 @@ +--- +display_name: Parsec +description: Enable low-latency remote desktop access using Parsec cloud gaming technology +icon: ../../../../.icons/parsec.svg +verified: true +tags: [remote-desktop, gaming, gpu, streaming] +--- + +# Parsec Module + +This module integrates [Parsec](https://parsec.app/) into your workspace for low-latency remote desktop access. Parsec provides high-performance streaming optimized for gaming and real-time interaction. + +## Features + +- High-performance remote desktop streaming +- GPU acceleration support +- Configurable streaming quality +- Automatic startup options +- Cross-platform client support + +## Prerequisites + +- A Linux-based workspace +- Parsec host key (obtain from [Parsec Settings](https://console.parsec.app/settings)) +- For GPU acceleration: NVIDIA GPU with appropriate drivers + +## Usage + +Basic usage: + +```hcl +module "parsec" { + source = "registry.coder.com/coder/parsec/coder" + version = "1.0.0" + agent_id = coder_agent.example.id + parsec_host_key = var.parsec_host_key +} +``` + +Advanced configuration: + +```hcl +module "parsec" { + source = "registry.coder.com/coder/parsec/coder" + version = "1.0.0" + agent_id = coder_agent.example.id + parsec_host_key = var.parsec_host_key + + enable_gpu_acceleration = true + auto_start = true + + parsec_config = { + encoder_bitrate = 50 # Mbps + encoder_fps = 60 + bandwidth_limit = 100 # Mbps + encoder_h265 = true + client_keyboard_layout = "en-us" + } +} +``` + +## Variables + +| Name | Description | Type | Default | +|------|-------------|------|---------| +| parsec_host_key | Parsec host key for authentication | string | required | +| parsec_version | Version of Parsec to install | string | "latest" | +| enable_gpu_acceleration | Enable GPU acceleration | bool | true | +| auto_start | Start Parsec daemon automatically | bool | true | +| parsec_config | Parsec configuration options | object | see below | + +### parsec_config Options + +```hcl +parsec_config = { + encoder_bitrate = 50 # Streaming bitrate in Mbps (1-100) + encoder_fps = 60 # Target framerate + bandwidth_limit = 100 # Bandwidth limit in Mbps + encoder_h265 = true # Use H.265 encoding when available + client_keyboard_layout = "en-us" # Keyboard layout +} +``` + +## How it Works + +1. **Installation**: The module installs Parsec and required dependencies +2. **Configuration**: Sets up Parsec with the provided host key and settings +3. **GPU Support**: Automatically configures GPU acceleration if available +4. **Autostart**: Optionally starts Parsec daemon on workspace startup + +## Client Setup + +1. Download the [Parsec client](https://parsec.app/downloads) for your platform +2. Log in with your Parsec account +3. Your workspace will appear in the "Computers" list +4. Click to connect and start streaming + +## Troubleshooting + +- If the stream quality is poor: + - Reduce encoder_bitrate or encoder_fps + - Check your network connection + - Verify GPU acceleration is working + +- If connection fails: + - Verify your host key is correct + - Check workspace firewall settings + - Ensure Parsec daemon is running + +## References + +- [Parsec Documentation](https://parsec.app/docs) +- [Host Computer Requirements](https://parsec.app/docs/hosting-specifications) +- [Parsec Linux Setup Guide](https://parsec.app/docs/linux) diff --git a/registry/coder/modules/parsec/main.tf b/registry/coder/modules/parsec/main.tf new file mode 100644 index 00000000..8c324b43 --- /dev/null +++ b/registry/coder/modules/parsec/main.tf @@ -0,0 +1,69 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + coder = { + source = "coder/coder" + version = ">= 2.7" + } + } +} + +variable "agent_id" { + type = string + description = "The ID of a Coder agent." +} + +variable "parsec_host_key" { + type = string + description = "The Parsec host key for authentication. Can be obtained from https://console.parsec.app/settings" + sensitive = true +} + +variable "parsec_version" { + type = string + description = "The version of Parsec to install. Use 'latest' for the most recent version." + default = "latest" +} + +variable "enable_gpu_acceleration" { + type = bool + description = "Whether to enable GPU acceleration for Parsec streaming." + default = true +} + +variable "auto_start" { + type = bool + description = "Whether to automatically start Parsec daemon on workspace startup." + default = true +} + +variable "parsec_config" { + type = object({ + encoder_bitrate = optional(number, 50) # Mbps + encoder_fps = optional(number, 60) + bandwidth_limit = optional(number, 100) # Mbps + encoder_h265 = optional(bool, true) + client_keyboard_layout = optional(string, "en-us") + }) + description = "Parsec configuration options" + default = {} +} + +data "coder_workspace" "me" {} + +resource "coder_script" "install_parsec" { + agent_id = var.agent_id + display_name = "Install Parsec" + icon = "/icon/parsec.svg" + script = file("${path.module}/scripts/install.sh") + run_on_start = true + + env = { + PARSEC_HOST_KEY = var.parsec_host_key + PARSEC_VERSION = var.parsec_version + ENABLE_GPU = tostring(var.enable_gpu_acceleration) + AUTO_START = tostring(var.auto_start) + PARSEC_CONFIG = jsonencode(var.parsec_config) + } +} diff --git a/registry/coder/modules/parsec/scripts/install.sh b/registry/coder/modules/parsec/scripts/install.sh new file mode 100644 index 00000000..9cc23986 --- /dev/null +++ b/registry/coder/modules/parsec/scripts/install.sh @@ -0,0 +1,118 @@ +#!/bin/bash +set -euo pipefail + +BOLD='\033[0;1m' +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Parse configuration +PARSEC_CONFIG=$(echo "$PARSEC_CONFIG" | base64 -d) + +printf "${BLUE}Starting Parsec installation...${NC}\n" + +# Check if we're running on a supported system +if [ "$(uname)" != "Linux" ]; then + printf "${RED}Error: This module only supports Linux systems${NC}\n" + exit 1 +fi + +# Install dependencies +printf "${BLUE}Installing dependencies...${NC}\n" +if command -v apt-get &> /dev/null; then + # Ubuntu/Debian + sudo apt-get update + sudo apt-get install -y \ + libegl1-mesa \ + libgl1-mesa-glx \ + libvdpau1 \ + x11-xserver-utils \ + pulseaudio \ + curl \ + jq +elif command -v dnf &> /dev/null; then + # Fedora/RHEL + sudo dnf install -y \ + mesa-libEGL \ + mesa-libGL \ + libvdpau \ + xorg-x11-server-utils \ + pulseaudio \ + curl \ + jq +else + printf "${RED}Error: Unsupported Linux distribution${NC}\n" + exit 1 +fi + +# Download and install Parsec +printf "${BLUE}Downloading Parsec...${NC}\n" +if [ "$PARSEC_VERSION" = "latest" ]; then + DOWNLOAD_URL="https://builds.parsec.app/package/parsec-linux.deb" +else + DOWNLOAD_URL="https://builds.parsec.app/package/parsec-linux-${PARSEC_VERSION}.deb" +fi + +wget -O /tmp/parsec.deb "$DOWNLOAD_URL" +sudo dpkg -i /tmp/parsec.deb || sudo apt-get -f install -y +rm /tmp/parsec.deb + +# Create Parsec configuration directory +PARSEC_CONFIG_DIR="$HOME/.config/parsec" +mkdir -p "$PARSEC_CONFIG_DIR" + +# Configure Parsec +printf "${BLUE}Configuring Parsec...${NC}\n" +cat > "$PARSEC_CONFIG_DIR/config.txt" << EOL +# Parsec Configuration +app_host = 1 +app_run_level = 3 +encoder_bitrate = $(jq -r '.encoder_bitrate // 50' <<< "$PARSEC_CONFIG") +encoder_fps = $(jq -r '.encoder_fps // 60' <<< "$PARSEC_CONFIG") +encoder_min_bitrate = 10 +bandwidth_limit = $(jq -r '.bandwidth_limit // 100' <<< "$PARSEC_CONFIG") +encoder_h265 = $(jq -r '.encoder_h265 // true' <<< "$PARSEC_CONFIG") +client_keyboard_layout = $(jq -r '.client_keyboard_layout // "en-us"' <<< "$PARSEC_CONFIG") +host_virtual_monitors = 1 +EOL + +# Configure host key +if [ -n "$PARSEC_HOST_KEY" ]; then + echo "host_key = $PARSEC_HOST_KEY" >> "$PARSEC_CONFIG_DIR/config.txt" +fi + +# Configure GPU acceleration if enabled +if [ "$ENABLE_GPU" = "true" ]; then + printf "${BLUE}Configuring GPU acceleration...${NC}\n" + # Check for NVIDIA GPU + if command -v nvidia-smi &> /dev/null; then + echo "encoder_device = 0" >> "$PARSEC_CONFIG_DIR/config.txt" + else + printf "${RED}Warning: GPU acceleration enabled but no NVIDIA GPU found${NC}\n" + fi +fi + +# Set up autostart if enabled +if [ "$AUTO_START" = "true" ]; then + printf "${BLUE}Configuring autostart...${NC}\n" + mkdir -p "$HOME/.config/autostart" + cat > "$HOME/.config/autostart/parsec.desktop" << EOL +[Desktop Entry] +Type=Application +Name=Parsec +Exec=parsecd +Hidden=false +NoDisplay=false +X-GNOME-Autostart-enabled=true +EOL +fi + +# Start Parsec daemon +if [ "$AUTO_START" = "true" ]; then + printf "${BLUE}Starting Parsec daemon...${NC}\n" + parsecd & +fi + +printf "${GREEN}Parsec installation and configuration complete!${NC}\n" +printf "You can now connect to this workspace using the Parsec client.\n"