Compare commits

..

2 Commits

Author SHA1 Message Date
Atif Ali 885c19e7bf fix(claude-code): default remote_control_name to workspace name 2026-03-11 17:38:56 +00:00
Atif Ali 1040aebd8b 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.
2026-03-11 17:38:24 +00:00
4 changed files with 88 additions and 2 deletions
@@ -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 = "Custom Name" # Optional: defaults to workspace name
}
```
### Usage with AWS Bedrock
#### Prerequisites
@@ -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. Defaults to the workspace name."
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 != "" ? var.remote_control_name : data.coder_workspace.me.name}' \
/tmp/start.sh
EOT
@@ -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
@@ -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
}