diff --git a/registry/coder/modules/claude-code/README.md b/registry/coder/modules/claude-code/README.md index 7bfa7590c..a58ed223b 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.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" claude_api_key = "xxxx-xxxxx-xxxx" @@ -47,7 +47,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.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" enable_boundary = true @@ -68,7 +68,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.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" enable_aibridge = true @@ -97,7 +97,7 @@ data "coder_task" "me" {} module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" ai_prompt = data.coder_task.me.prompt @@ -120,7 +120,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.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" @@ -176,7 +176,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.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" install_claude_code = true @@ -198,7 +198,7 @@ variable "claude_code_oauth_token" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" claude_code_oauth_token = var.claude_code_oauth_token @@ -271,7 +271,7 @@ resource "coder_env" "bedrock_api_key" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0" @@ -328,7 +328,7 @@ resource "coder_env" "google_application_credentials" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.7.3" + version = "4.7.4" agent_id = coder_agent.main.id workdir = "/home/coder/project" model = "claude-sonnet-4@20250514" diff --git a/registry/coder/modules/claude-code/main.tf b/registry/coder/modules/claude-code/main.tf index bfb1ad159..3ed4a0210 100644 --- a/registry/coder/modules/claude-code/main.tf +++ b/registry/coder/modules/claude-code/main.tf @@ -276,9 +276,11 @@ resource "coder_env" "claude_code_oauth_token" { } resource "coder_env" "claude_api_key" { + count = local.claude_api_key != "" ? 1 : 0 + agent_id = var.agent_id name = "CLAUDE_API_KEY" - value = var.enable_aibridge ? data.coder_workspace_owner.me.session_token : var.claude_api_key + value = local.claude_api_key } resource "coder_env" "disable_autoupdater" { @@ -324,7 +326,8 @@ locals { start_script = file("${path.module}/scripts/start.sh") module_dir_name = ".claude-module" # Extract hostname from access_url for boundary --allow flag - coder_host = replace(replace(data.coder_workspace.me.access_url, "https://", ""), "http://", "") + coder_host = replace(replace(data.coder_workspace.me.access_url, "https://", ""), "http://", "") + claude_api_key = var.enable_aibridge ? data.coder_workspace_owner.me.session_token : var.claude_api_key # Required prompts for the module to properly report task status to Coder report_tasks_system_prompt = <<-EOT diff --git a/registry/coder/modules/claude-code/main.tftest.hcl b/registry/coder/modules/claude-code/main.tftest.hcl index 55106170f..e273d3211 100644 --- a/registry/coder/modules/claude-code/main.tftest.hcl +++ b/registry/coder/modules/claude-code/main.tftest.hcl @@ -42,7 +42,7 @@ run "test_claude_code_with_api_key" { } assert { - condition = coder_env.claude_api_key.value == "test-api-key-123" + condition = coder_env.claude_api_key[0].value == "test-api-key-123" error_message = "Claude API key value should match the input" } } @@ -298,6 +298,13 @@ run "test_aibridge_enabled" { enable_aibridge = true } + override_data { + target = data.coder_workspace_owner.me + values = { + session_token = "mock-session-token" + } + } + assert { condition = var.enable_aibridge == true error_message = "AI Bridge should be enabled" @@ -314,12 +321,12 @@ run "test_aibridge_enabled" { } assert { - condition = coder_env.claude_api_key.name == "CLAUDE_API_KEY" + condition = coder_env.claude_api_key[0].name == "CLAUDE_API_KEY" error_message = "CLAUDE_API_KEY environment variable should be set" } assert { - condition = coder_env.claude_api_key.value == data.coder_workspace_owner.me.session_token + condition = coder_env.claude_api_key[0].value == data.coder_workspace_owner.me.session_token error_message = "CLAUDE_API_KEY should use workspace owner's session token when aibridge is enabled" } } @@ -370,7 +377,7 @@ run "test_aibridge_disabled_with_api_key" { } assert { - condition = coder_env.claude_api_key.value == "test-api-key-xyz" + condition = coder_env.claude_api_key[0].value == "test-api-key-xyz" error_message = "CLAUDE_API_KEY should use the provided API key when aibridge is disabled" } @@ -379,3 +386,18 @@ run "test_aibridge_disabled_with_api_key" { error_message = "ANTHROPIC_BASE_URL should not be set when aibridge is disabled" } } + +run "test_no_api_key_no_env" { + command = plan + + variables { + agent_id = "test-agent-no-key" + workdir = "/home/coder/test" + enable_aibridge = false + } + + assert { + condition = length(coder_env.claude_api_key) == 0 + error_message = "CLAUDE_API_KEY should not be created when no API key is provided and aibridge is disabled" + } +}