From 494ad9bd48961ca228a3a0a36a8663d79c42fdc7 Mon Sep 17 00:00:00 2001 From: Atif Ali Date: Sat, 4 Apr 2026 19:42:33 +0000 Subject: [PATCH 1/3] fix(copilot): remove hardcoded model enum to allow any Copilot model (#833) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `copilot_model` variable was restricted to a hardcoded enum of three models (`claude-sonnet-4`, `claude-sonnet-4.5`, `gpt-5`). Models change fast and this validation was blocking users from using newer models. ## Changes - Remove `validation` block from `copilot_model` variable in `main.tf` - Update variable description to indicate any Copilot-supported model can be used - Replace enum validation test with a test that verifies arbitrary model strings are accepted - Bump module version to `0.4.1` in README examples Closes #832 > 🤖 This PR was created with the help of Coder Agents, and needs a human review. 🧑‍💻 --- registry/coder-labs/modules/copilot/README.md | 12 ++++++------ .../coder-labs/modules/copilot/copilot.tftest.hcl | 13 +++++++++---- registry/coder-labs/modules/copilot/main.tf | 6 +----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/registry/coder-labs/modules/copilot/README.md b/registry/coder-labs/modules/copilot/README.md index 7c0e5693..24fd5b51 100644 --- a/registry/coder-labs/modules/copilot/README.md +++ b/registry/coder-labs/modules/copilot/README.md @@ -13,7 +13,7 @@ Run [GitHub Copilot CLI](https://docs.github.com/copilot/concepts/agents/about-c ```tf module "copilot" { source = "registry.coder.com/coder-labs/copilot/coder" - version = "0.4.0" + version = "0.4.1" agent_id = coder_agent.example.id workdir = "/home/coder/projects" } @@ -51,7 +51,7 @@ data "coder_parameter" "ai_prompt" { module "copilot" { source = "registry.coder.com/coder-labs/copilot/coder" - version = "0.4.0" + version = "0.4.1" agent_id = coder_agent.example.id workdir = "/home/coder/projects" @@ -71,7 +71,7 @@ Customize tool permissions, MCP servers, and Copilot settings: ```tf module "copilot" { source = "registry.coder.com/coder-labs/copilot/coder" - version = "0.4.0" + version = "0.4.1" agent_id = coder_agent.example.id workdir = "/home/coder/projects" @@ -142,7 +142,7 @@ variable "github_token" { module "copilot" { source = "registry.coder.com/coder-labs/copilot/coder" - version = "0.4.0" + version = "0.4.1" agent_id = coder_agent.example.id workdir = "/home/coder/projects" github_token = var.github_token @@ -156,7 +156,7 @@ Run Copilot as a command-line tool without task reporting or web interface. This ```tf module "copilot" { source = "registry.coder.com/coder-labs/copilot/coder" - version = "0.4.0" + version = "0.4.1" agent_id = coder_agent.example.id workdir = "/home/coder" report_tasks = false @@ -179,7 +179,7 @@ module "aibridge-proxy" { module "copilot" { source = "registry.coder.com/coder-labs/copilot/coder" - version = "0.4.0" + version = "0.4.1" agent_id = coder_agent.main.id workdir = "/home/coder/projects" enable_aibridge_proxy = true diff --git a/registry/coder-labs/modules/copilot/copilot.tftest.hcl b/registry/coder-labs/modules/copilot/copilot.tftest.hcl index 0ff2379a..ec5a3668 100644 --- a/registry/coder-labs/modules/copilot/copilot.tftest.hcl +++ b/registry/coder-labs/modules/copilot/copilot.tftest.hcl @@ -117,18 +117,23 @@ run "copilot_model_not_created_for_default" { } } -run "model_validation_accepts_valid_models" { +run "copilot_model_accepts_custom_model" { command = plan variables { agent_id = "test-agent" workdir = "/home/coder" - copilot_model = "gpt-5" + copilot_model = "o3-pro" } assert { - condition = contains(["claude-sonnet-4", "claude-sonnet-4.5", "gpt-5"], var.copilot_model) - error_message = "Model should be one of the valid options" + condition = var.copilot_model == "o3-pro" + error_message = "copilot_model should accept any model string" + } + + assert { + condition = length(resource.coder_env.copilot_model) == 1 + error_message = "copilot_model env var should be created for non-default model" } } diff --git a/registry/coder-labs/modules/copilot/main.tf b/registry/coder-labs/modules/copilot/main.tf index 2837961f..268ba69c 100644 --- a/registry/coder-labs/modules/copilot/main.tf +++ b/registry/coder-labs/modules/copilot/main.tf @@ -33,12 +33,8 @@ variable "github_token" { variable "copilot_model" { type = string - description = "Model to use. Supported values: claude-sonnet-4, claude-sonnet-4.5 (default), gpt-5." + description = "The model to use for Copilot. Any model supported by GitHub Copilot can be used." default = "claude-sonnet-4.5" - validation { - condition = contains(["claude-sonnet-4", "claude-sonnet-4.5", "gpt-5"], var.copilot_model) - error_message = "copilot_model must be one of: claude-sonnet-4, claude-sonnet-4.5, gpt-5." - } } variable "copilot_config" { From de7bd0102112edddecc0668b9326338ebd3a1dac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 22:10:34 +0500 Subject: [PATCH 2/3] chore(deps): bump the github-actions group with 2 updates (#834) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yaml | 6 +++--- .github/workflows/version-bump.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 809cf06b..6fa4341e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,7 +37,7 @@ jobs: all: - '**' - name: Set up Terraform - uses: coder/coder/.github/actions/setup-tf@f7650296ceb9b020c79cd525ac7bd3c7f252ae1d # v2.31.6 + uses: coder/coder/.github/actions/setup-tf@a7e9dfa7dc18625e4e0c155af3b0928a8cb3354a # v2.31.7 - name: Set up Bun uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: @@ -87,13 +87,13 @@ jobs: bun-version: latest # Need Terraform for its formatter - name: Install Terraform - uses: coder/coder/.github/actions/setup-tf@f7650296ceb9b020c79cd525ac7bd3c7f252ae1d # v2.31.6 + uses: coder/coder/.github/actions/setup-tf@a7e9dfa7dc18625e4e0c155af3b0928a8cb3354a # v2.31.7 - name: Install dependencies run: bun install - name: Validate formatting run: bun fmt:ci - name: Check for typos - uses: crate-ci/typos@631208b7aac2daa8b707f55e7331f9112b0e062d # v1.44.0 + uses: crate-ci/typos@02ea592e44b3a53c302f697cddca7641cd051c3d # v1.45.0 with: config: .github/typos.toml validate-readme-files: diff --git a/.github/workflows/version-bump.yaml b/.github/workflows/version-bump.yaml index 77f7e1f6..650e691f 100644 --- a/.github/workflows/version-bump.yaml +++ b/.github/workflows/version-bump.yaml @@ -31,7 +31,7 @@ jobs: bun-version: latest - name: Set up Terraform - uses: coder/coder/.github/actions/setup-tf@f7650296ceb9b020c79cd525ac7bd3c7f252ae1d # v2.31.6 + uses: coder/coder/.github/actions/setup-tf@a7e9dfa7dc18625e4e0c155af3b0928a8cb3354a # v2.31.7 - name: Install dependencies run: bun install From d3885a504787a29d10ebc85737e2873ed7d79b42 Mon Sep 17 00:00:00 2001 From: Max Schwenk Date: Tue, 7 Apr 2026 14:59:36 -0400 Subject: [PATCH 3/3] feat: add auto permission mode to claude-code module (#830) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add `auto` as a valid `permission_mode` for the claude-code module, passing `--enable-auto-mode` to the CLI when selected - Fix bypass permissions TOS prompt appearing interactively by pre-seeding `bypassPermissionsModeAccepted` in `~/.claude.json` during install (workaround for https://github.com/anthropics/claude-code/issues/25503) - Bump version `4.8.2` → `4.9.0` ## Test plan - [x] All 19 terraform tests pass (`terraform test -verbose`) - [x] Added `test_claude_code_auto_permission_mode` tftest - [x] Added `claude-auto-permission-mode` TypeScript test verifying both `--permission-mode auto` and `--enable-auto-mode` are passed - [ ] Container test with auto mode (requires Linux/Colima) - [ ] Verify bypass permissions TOS prompt no longer appears on task startup 🤖 Generated with Claude Code using Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 (1M context) Co-authored-by: DevCats --- registry/coder/modules/claude-code/README.md | 18 ++++++------- .../coder/modules/claude-code/main.test.ts | 18 +++++++++++++ registry/coder/modules/claude-code/main.tf | 5 ++-- .../coder/modules/claude-code/main.tftest.hcl | 17 ++++++++++++- .../modules/claude-code/scripts/install.sh | 25 +++++++++++++++++++ 5 files changed, 71 insertions(+), 12 deletions(-) diff --git a/registry/coder/modules/claude-code/README.md b/registry/coder/modules/claude-code/README.md index ea845f6e..48b291bb 100644 --- a/registry/coder/modules/claude-code/README.md +++ b/registry/coder/modules/claude-code/README.md @@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" claude_api_key = "xxxx-xxxxx-xxxx" @@ -60,7 +60,7 @@ By default, when `enable_boundary = true`, the module uses `coder boundary` subc ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" enable_boundary = true @@ -81,7 +81,7 @@ For tasks integration with AI Bridge, add `enable_aibridge = true` to the [Usage ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" enable_aibridge = true @@ -110,7 +110,7 @@ data "coder_task" "me" {} module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" ai_prompt = data.coder_task.me.prompt @@ -133,7 +133,7 @@ This example shows additional configuration options for version pinning, custom ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" @@ -189,7 +189,7 @@ Run and configure Claude Code as a standalone CLI in your workspace. ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" install_claude_code = true @@ -211,7 +211,7 @@ variable "claude_code_oauth_token" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" claude_code_oauth_token = var.claude_code_oauth_token @@ -284,7 +284,7 @@ resource "coder_env" "bedrock_api_key" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0" @@ -341,7 +341,7 @@ resource "coder_env" "google_application_credentials" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.9.1" + version = "4.9.2" agent_id = coder_agent.main.id workdir = "/home/coder/project" model = "claude-sonnet-4@20250514" diff --git a/registry/coder/modules/claude-code/main.test.ts b/registry/coder/modules/claude-code/main.test.ts index 19ab98c0..b01e8832 100644 --- a/registry/coder/modules/claude-code/main.test.ts +++ b/registry/coder/modules/claude-code/main.test.ts @@ -182,6 +182,24 @@ describe("claude-code", async () => { expect(startLog.stdout).toContain(`--permission-mode ${mode}`); }); + test("claude-auto-permission-mode", async () => { + const mode = "auto"; + const { id } = await setup({ + moduleVariables: { + permission_mode: mode, + ai_prompt: "test prompt", + }, + }); + await execModuleScript(id); + + const startLog = await execContainer(id, [ + "bash", + "-c", + "cat /home/coder/.claude-module/agentapi-start.log", + ]); + expect(startLog.stdout).toContain(`--permission-mode ${mode}`); + }); + test("claude-model", async () => { const model = "opus"; const { coderEnvVars } = await setup({ diff --git a/registry/coder/modules/claude-code/main.tf b/registry/coder/modules/claude-code/main.tf index 7a08aa82..db234c05 100644 --- a/registry/coder/modules/claude-code/main.tf +++ b/registry/coder/modules/claude-code/main.tf @@ -161,8 +161,8 @@ variable "permission_mode" { description = "Permission mode for the cli, check https://docs.anthropic.com/en/docs/claude-code/iam#permission-modes" default = "" validation { - condition = contains(["", "default", "acceptEdits", "plan", "bypassPermissions"], var.permission_mode) - error_message = "interaction_mode must be one of: default, acceptEdits, plan, bypassPermissions." + condition = contains(["", "default", "acceptEdits", "plan", "auto", "bypassPermissions"], var.permission_mode) + error_message = "interaction_mode must be one of: default, acceptEdits, plan, auto, bypassPermissions." } } @@ -430,6 +430,7 @@ module "agentapi" { ARG_MCP='${var.mcp != null ? base64encode(replace(var.mcp, "'", "'\\''")) : ""}' \ ARG_MCP_CONFIG_REMOTE_PATH='${base64encode(jsonencode(var.mcp_config_remote_path))}' \ ARG_ENABLE_AIBRIDGE='${var.enable_aibridge}' \ + ARG_PERMISSION_MODE='${var.permission_mode}' \ /tmp/install.sh EOT } diff --git a/registry/coder/modules/claude-code/main.tftest.hcl b/registry/coder/modules/claude-code/main.tftest.hcl index 66c79bab..9c9df50f 100644 --- a/registry/coder/modules/claude-code/main.tftest.hcl +++ b/registry/coder/modules/claude-code/main.tftest.hcl @@ -183,11 +183,26 @@ run "test_claude_code_permission_mode_validation" { } assert { - condition = contains(["", "default", "acceptEdits", "plan", "bypassPermissions"], var.permission_mode) + condition = contains(["", "default", "acceptEdits", "plan", "auto", "bypassPermissions"], var.permission_mode) error_message = "Permission mode should be one of the valid options" } } +run "test_claude_code_auto_permission_mode" { + command = plan + + variables { + agent_id = "test-agent-auto" + workdir = "/home/coder/test" + permission_mode = "auto" + } + + assert { + condition = var.permission_mode == "auto" + error_message = "Permission mode should be set to auto" + } +} + run "test_claude_code_with_boundary" { command = plan diff --git a/registry/coder/modules/claude-code/scripts/install.sh b/registry/coder/modules/claude-code/scripts/install.sh index 0a2ba703..c00773b5 100644 --- a/registry/coder/modules/claude-code/scripts/install.sh +++ b/registry/coder/modules/claude-code/scripts/install.sh @@ -22,6 +22,7 @@ ARG_MCP_CONFIG_REMOTE_PATH=$(echo -n "${ARG_MCP_CONFIG_REMOTE_PATH:-}" | base64 ARG_ALLOWED_TOOLS=${ARG_ALLOWED_TOOLS:-} ARG_DISALLOWED_TOOLS=${ARG_DISALLOWED_TOOLS:-} ARG_ENABLE_AIBRIDGE=${ARG_ENABLE_AIBRIDGE:-false} +ARG_PERMISSION_MODE=${ARG_PERMISSION_MODE:-} export PATH="$ARG_CLAUDE_BINARY_PATH:$PATH" @@ -195,6 +196,7 @@ function configure_standalone_mode() { jq --arg workdir "$ARG_WORKDIR" --arg apikey "${CLAUDE_API_KEY:-}" \ '.autoUpdaterStatus = "disabled" | + .autoModeAccepted = true | .bypassPermissionsModeAccepted = true | .hasAcknowledgedCostThreshold = true | .hasCompletedOnboarding = true | @@ -207,6 +209,7 @@ function configure_standalone_mode() { cat > "$claude_config" << EOF { "autoUpdaterStatus": "disabled", + "autoModeAccepted": true, "bypassPermissionsModeAccepted": true, "hasAcknowledgedCostThreshold": true, "hasCompletedOnboarding": true, @@ -235,6 +238,28 @@ function report_tasks() { fi } +function accept_auto_mode() { + # Pre-accept the auto mode TOS prompt so it doesn't appear interactively. + # Claude Code shows a confirmation dialog for auto mode that blocks + # non-interactive/headless usage. + # Note: bypassPermissions acceptance is already handled by + # coder exp mcp configure (task mode) and configure_standalone_mode. + local claude_config="$HOME/.claude.json" + + if [ -f "$claude_config" ]; then + jq '.autoModeAccepted = true' \ + "$claude_config" > "${claude_config}.tmp" && mv "${claude_config}.tmp" "$claude_config" + else + echo '{"autoModeAccepted": true}' > "$claude_config" + fi + + echo "Pre-accepted auto mode prompt" +} + install_claude_code_cli setup_claude_configurations report_tasks + +if [ "$ARG_PERMISSION_MODE" = "auto" ]; then + accept_auto_mode +fi