diff --git a/registry/coder/modules/claude-code/README.md b/registry/coder/modules/claude-code/README.md index 8e98a880a..984830f92 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.6.0" + version = "4.7.0" agent_id = coder_agent.main.id workdir = "/home/coder/project" claude_api_key = "xxxx-xxxxx-xxxx" @@ -42,17 +42,21 @@ By default, Claude Code automatically resumes existing conversations when your w This example shows how to configure the Claude Code module to run the agent behind a process-level boundary that restricts its network access. +By default, when `enable_boundary = true`, the module uses `coder boundary` subcommand (provided by Coder) without requiring any installation. + ```tf module "claude-code" { - source = "registry.coder.com/coder/claude-code/coder" - version = "4.6.0" - agent_id = coder_agent.main.id - workdir = "/home/coder/project" - enable_boundary = true - boundary_version = "v0.5.1" + source = "registry.coder.com/coder/claude-code/coder" + version = "4.7.0" + agent_id = coder_agent.main.id + workdir = "/home/coder/project" + enable_boundary = true } ``` +> [!NOTE] +> For developers: The module also supports installing boundary from a release version (`use_boundary_directly = true`) or compiling from source (`compile_boundary_from_source = true`). These are escape hatches for development and testing purposes. + ### Usage with AI Bridge [AI Bridge](https://coder.com/docs/ai-coder/ai-bridge) is a Premium Coder feature that provides centralized LLM proxy management. To use AI Bridge, set `enable_aibridge = true`. @@ -64,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.6.0" + version = "4.7.0" agent_id = coder_agent.main.id workdir = "/home/coder/project" enable_aibridge = true @@ -93,7 +97,7 @@ data "coder_task" "me" {} module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.6.0" + version = "4.7.0" agent_id = coder_agent.main.id workdir = "/home/coder/project" claude_api_key = "xxxx-xxxxx-xxxx" @@ -114,7 +118,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.6.0" + version = "4.7.0" agent_id = coder_agent.main.id workdir = "/home/coder/project" @@ -170,7 +174,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.6.0" + version = "4.7.0" agent_id = coder_agent.main.id workdir = "/home/coder/project" install_claude_code = true @@ -192,7 +196,7 @@ variable "claude_code_oauth_token" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.6.0" + version = "4.7.0" agent_id = coder_agent.main.id workdir = "/home/coder/project" claude_code_oauth_token = var.claude_code_oauth_token @@ -265,7 +269,7 @@ resource "coder_env" "bedrock_api_key" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.6.0" + version = "4.7.0" agent_id = coder_agent.main.id workdir = "/home/coder/project" model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0" @@ -322,7 +326,7 @@ resource "coder_env" "google_application_credentials" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "4.6.0" + version = "4.7.0" 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 3a1128b48..8c4bd08e2 100644 --- a/registry/coder/modules/claude-code/main.tf +++ b/registry/coder/modules/claude-code/main.tf @@ -234,6 +234,12 @@ variable "compile_boundary_from_source" { default = false } +variable "use_boundary_directly" { + type = bool + description = "Whether to use boundary binary directly instead of coder boundary subcommand. When false (default), uses coder boundary subcommand. When true, installs and uses boundary binary from release." + default = false +} + variable "enable_aibridge" { type = bool description = "Use AI Bridge for Claude Code. https://coder.com/docs/ai-coder/ai-bridge" @@ -389,6 +395,7 @@ module "agentapi" { ARG_ENABLE_BOUNDARY='${var.enable_boundary}' \ ARG_BOUNDARY_VERSION='${var.boundary_version}' \ ARG_COMPILE_FROM_SOURCE='${var.compile_boundary_from_source}' \ + ARG_USE_BOUNDARY_DIRECTLY='${var.use_boundary_directly}' \ ARG_CODER_HOST='${local.coder_host}' \ /tmp/start.sh EOT diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index c3c320209..f64c77c11 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -16,6 +16,7 @@ ARG_REPORT_TASKS=${ARG_REPORT_TASKS:-true} ARG_ENABLE_BOUNDARY=${ARG_ENABLE_BOUNDARY:-false} ARG_BOUNDARY_VERSION=${ARG_BOUNDARY_VERSION:-"main"} ARG_COMPILE_FROM_SOURCE=${ARG_COMPILE_FROM_SOURCE:-false} +ARG_USE_BOUNDARY_DIRECTLY=${ARG_USE_BOUNDARY_DIRECTLY:-false} ARG_CODER_HOST=${ARG_CODER_HOST:-} echo "--------------------------------" @@ -30,12 +31,13 @@ printf "ARG_REPORT_TASKS: %s\n" "$ARG_REPORT_TASKS" printf "ARG_ENABLE_BOUNDARY: %s\n" "$ARG_ENABLE_BOUNDARY" printf "ARG_BOUNDARY_VERSION: %s\n" "$ARG_BOUNDARY_VERSION" printf "ARG_COMPILE_FROM_SOURCE: %s\n" "$ARG_COMPILE_FROM_SOURCE" +printf "ARG_USE_BOUNDARY_DIRECTLY: %s\n" "$ARG_USE_BOUNDARY_DIRECTLY" printf "ARG_CODER_HOST: %s\n" "$ARG_CODER_HOST" echo "--------------------------------" function install_boundary() { - if [ "${ARG_COMPILE_FROM_SOURCE:-false}" = "true" ]; then + if [ "$ARG_COMPILE_FROM_SOURCE" = "true" ]; then # Install boundary by compiling from source echo "Compiling boundary from source (version: $ARG_BOUNDARY_VERSION)" @@ -52,14 +54,16 @@ function install_boundary() { # Build the binary make build - # Install binary and wrapper script (optional) + # Install binary sudo cp boundary /usr/local/bin/ - sudo cp scripts/boundary-wrapper.sh /usr/local/bin/boundary-run - sudo chmod +x /usr/local/bin/boundary-run - else + sudo chmod +x /usr/local/bin/boundary + elif [ "$ARG_USE_BOUNDARY_DIRECTLY" = "true" ]; then # Install boundary using official install script echo "Installing boundary using official install script (version: $ARG_BOUNDARY_VERSION)" curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | bash -s -- --version "$ARG_BOUNDARY_VERSION" + else + # Use coder boundary subcommand (default) - no installation needed + echo "Using coder boundary subcommand (provided by Coder)" fi } @@ -212,15 +216,30 @@ function start_agentapi() { printf "Running claude code with args: %s\n" "$(printf '%q ' "${ARGS[@]}")" - if [ "${ARG_ENABLE_BOUNDARY:-false}" = "true" ]; then + if [ "$ARG_ENABLE_BOUNDARY" = "true" ]; then install_boundary printf "Starting with coder boundary enabled\n" BOUNDARY_ARGS+=() + # Determine which boundary command to use + if [ "$ARG_COMPILE_FROM_SOURCE" = "true" ] || [ "$ARG_USE_BOUNDARY_DIRECTLY" = "true" ]; then + # Use boundary binary directly (from compilation or release installation) + BOUNDARY_CMD=("boundary") + else + # Use coder boundary subcommand (default) + # Copy coder binary to coder-no-caps. Copying strips CAP_NET_ADMIN capabilities + # from the binary, which is necessary because boundary doesn't work with + # privileged binaries (you can't launch privileged binaries inside network + # namespaces unless you have sys_admin). + CODER_NO_CAPS="$(dirname "$(which coder)")/coder-no-caps" + cp "$(which coder)" "$CODER_NO_CAPS" + BOUNDARY_CMD=("$CODER_NO_CAPS" "boundary") + fi + agentapi server --type claude --term-width 67 --term-height 1190 -- \ - boundary-run "${BOUNDARY_ARGS[@]}" -- \ + "${BOUNDARY_CMD[@]}" "${BOUNDARY_ARGS[@]}" -- \ claude "${ARGS[@]}" else agentapi server --type claude --term-width 67 --term-height 1190 -- claude "${ARGS[@]}"