From 1040aebd8b1c0ad456ab7660410b0b1c599ea142 Mon Sep 17 00:00:00 2001 From: Atif Ali Date: Wed, 11 Mar 2026 17:38:24 +0000 Subject: [PATCH] feat(claude-code): add optional remote control support Add enable_remote_control and remote_control_name variables to the claude-code module, allowing users to opt into Claude Code Remote Control (https://code.claude.com/docs/en/remote-control.md). When enabled, the module starts claude in remote-control mode instead of the default interactive mode, allowing the session to be accessed from claude.ai/code or the Claude mobile app. Requires a Claude subscription (Pro, Max, Team, or Enterprise). API keys are not supported. --- registry/coder/modules/claude-code/README.md | 19 +++++++++ registry/coder/modules/claude-code/main.tf | 14 +++++++ .../coder/modules/claude-code/main.tftest.hcl | 40 +++++++++++++++++++ .../modules/claude-code/scripts/start.sh | 17 +++++++- 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/registry/coder/modules/claude-code/README.md b/registry/coder/modules/claude-code/README.md index 3d875046..d75b26fe 100644 --- a/registry/coder/modules/claude-code/README.md +++ b/registry/coder/modules/claude-code/README.md @@ -218,6 +218,25 @@ module "claude-code" { } ``` +### Usage with Remote Control + +[Remote Control](https://code.claude.com/docs/en/remote-control.md) allows you to access your Claude Code session from [claude.ai/code](https://claude.ai/code) or the Claude mobile app. The session runs locally in your workspace while you interact with it from any browser or device. + +> [!NOTE] +> Remote Control requires a Claude subscription (Pro, Max, Team, or Enterprise). API keys are not supported. You must authenticate using `claude_code_oauth_token`. + +```tf +module "claude-code" { + source = "registry.coder.com/coder/claude-code/coder" + version = "4.8.0" + agent_id = coder_agent.main.id + workdir = "/home/coder/project" + claude_code_oauth_token = var.claude_code_oauth_token + enable_remote_control = true + remote_control_name = "My Project" # Optional: custom session name +} +``` + ### Usage with AWS Bedrock #### Prerequisites diff --git a/registry/coder/modules/claude-code/main.tf b/registry/coder/modules/claude-code/main.tf index 337ebd20..6a9f2496 100644 --- a/registry/coder/modules/claude-code/main.tf +++ b/registry/coder/modules/claude-code/main.tf @@ -267,6 +267,18 @@ variable "enable_state_persistence" { default = true } +variable "enable_remote_control" { + type = bool + description = "Enable Claude Code Remote Control, allowing the session to be accessed from claude.ai/code or the Claude mobile app. Requires a Claude subscription (Pro, Max, Team, or Enterprise). API keys are not supported. See https://code.claude.com/docs/en/remote-control.md" + default = false +} + +variable "remote_control_name" { + type = string + description = "Custom session name for Remote Control, visible in the session list at claude.ai/code. Only used when enable_remote_control is true." + default = "" +} + resource "coder_env" "claude_code_md_path" { count = var.claude_md_path == "" ? 0 : 1 agent_id = var.agent_id @@ -401,6 +413,8 @@ module "agentapi" { ARG_USE_BOUNDARY_DIRECTLY='${var.use_boundary_directly}' \ ARG_CODER_HOST='${local.coder_host}' \ ARG_CLAUDE_BINARY_PATH='${var.claude_binary_path}' \ + ARG_ENABLE_REMOTE_CONTROL='${var.enable_remote_control}' \ + ARG_REMOTE_CONTROL_NAME='${var.remote_control_name}' \ /tmp/start.sh EOT diff --git a/registry/coder/modules/claude-code/main.tftest.hcl b/registry/coder/modules/claude-code/main.tftest.hcl index 3d11989b..ab315fed 100644 --- a/registry/coder/modules/claude-code/main.tftest.hcl +++ b/registry/coder/modules/claude-code/main.tftest.hcl @@ -417,6 +417,46 @@ run "test_disable_state_persistence" { } +run "test_enable_remote_control_default" { + command = plan + + variables { + agent_id = "test-agent" + workdir = "/home/coder" + } + + assert { + condition = var.enable_remote_control == false + error_message = "enable_remote_control should default to false" + } + + assert { + condition = var.remote_control_name == "" + error_message = "remote_control_name should default to empty string" + } +} + +run "test_enable_remote_control" { + command = plan + + variables { + agent_id = "test-agent-rc" + workdir = "/home/coder/project" + enable_remote_control = true + remote_control_name = "My Project" + } + + assert { + condition = var.enable_remote_control == true + error_message = "enable_remote_control should be true when explicitly enabled" + } + + assert { + condition = var.remote_control_name == "My Project" + error_message = "remote_control_name should be set to 'My Project'" + } +} + run "test_no_api_key_no_env" { command = plan diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index 2df8fce1..a44c0b8d 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -24,6 +24,8 @@ ARG_BOUNDARY_VERSION=${ARG_BOUNDARY_VERSION:-"latest"} ARG_COMPILE_FROM_SOURCE=${ARG_COMPILE_FROM_SOURCE:-false} ARG_USE_BOUNDARY_DIRECTLY=${ARG_USE_BOUNDARY_DIRECTLY:-false} ARG_CODER_HOST=${ARG_CODER_HOST:-} +ARG_ENABLE_REMOTE_CONTROL=${ARG_ENABLE_REMOTE_CONTROL:-false} +ARG_REMOTE_CONTROL_NAME=${ARG_REMOTE_CONTROL_NAME:-} echo "--------------------------------" @@ -39,6 +41,8 @@ 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" +printf "ARG_ENABLE_REMOTE_CONTROL: %s\n" "$ARG_ENABLE_REMOTE_CONTROL" +printf "ARG_REMOTE_CONTROL_NAME: %s\n" "$ARG_REMOTE_CONTROL_NAME" echo "--------------------------------" @@ -220,6 +224,15 @@ function start_agentapi() { [ -n "$ARG_AI_PROMPT" ] && ARGS+=(-- "$ARG_AI_PROMPT") fi + # Build the claude command - either regular or remote-control mode. + CLAUDE_CMD=("claude") + if [ "$ARG_ENABLE_REMOTE_CONTROL" = "true" ]; then + CLAUDE_CMD+=("remote-control") + if [ -n "$ARG_REMOTE_CONTROL_NAME" ]; then + CLAUDE_CMD+=("--name" "$ARG_REMOTE_CONTROL_NAME") + fi + fi + printf "Running claude code with args: %s\n" "$(printf '%q ' "${ARGS[@]}")" if [ "$ARG_ENABLE_BOUNDARY" = "true" ]; then @@ -246,9 +259,9 @@ function start_agentapi() { agentapi server --type claude --term-width 67 --term-height 1190 -- \ "${BOUNDARY_CMD[@]}" "${BOUNDARY_ARGS[@]}" -- \ - claude "${ARGS[@]}" + "${CLAUDE_CMD[@]}" "${ARGS[@]}" else - agentapi server --type claude --term-width 67 --term-height 1190 -- claude "${ARGS[@]}" + agentapi server --type claude --term-width 67 --term-height 1190 -- "${CLAUDE_CMD[@]}" "${ARGS[@]}" fi }