Skip to content

feat(claude-code): use tmux instead of screen #432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions claude-code/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude
```tf
module "claude-code" {
source = "registry.coder.com/modules/claude-code/coder"
version = "1.0.31"
version = "1.1.0"
agent_id = coder_agent.example.id
folder = "/home/coder"
install_claude_code = true
Expand All @@ -25,7 +25,7 @@ module "claude-code" {
### Prerequisites

- Node.js and npm must be installed in your workspace to install Claude Code
- `screen` must be installed in your workspace to run Claude Code in the background
- Either `screen` or `tmux` must be installed in your workspace to run Claude Code in the background
- You must add the [Coder Login](https://registry.coder.com/modules/coder-login) module to your template

The `codercom/oss-dogfood:latest` container image can be used for testing on container-based workspaces.
Expand All @@ -43,7 +43,7 @@ The `codercom/oss-dogfood:latest` container image can be used for testing on con
> Join our [Discord channel](https://discord.gg/coder) or
> [contact us](https://coder.com/contact) to get help or share feedback.

Your workspace must have `screen` installed to use this.
Your workspace must have either `screen` or `tmux` installed to use this.

```tf
variable "anthropic_api_key" {
Expand Down Expand Up @@ -83,14 +83,14 @@ resource "coder_agent" "main" {
module "claude-code" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/claude-code/coder"
version = "1.0.31"
version = "1.1.0"
agent_id = coder_agent.example.id
folder = "/home/coder"
install_claude_code = true
claude_code_version = "0.2.57"

# Enable experimental features
experiment_use_screen = true
experiment_use_screen = true # Or use experiment_use_tmux = true to use tmux instead
experiment_report_tasks = true
}
```
Expand All @@ -102,7 +102,7 @@ Run Claude Code as a standalone app in your workspace. This will install Claude
```tf
module "claude-code" {
source = "registry.coder.com/modules/claude-code/coder"
version = "1.0.31"
version = "1.1.0"
agent_id = coder_agent.example.id
folder = "/home/coder"
install_claude_code = true
Expand Down
62 changes: 54 additions & 8 deletions claude-code/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ variable "experiment_use_screen" {
default = false
}

variable "experiment_use_tmux" {
type = bool
description = "Whether to use tmux instead of screen for running Claude Code in the background."
default = false
}

variable "experiment_report_tasks" {
type = bool
description = "Whether to enable task reporting."
Expand Down Expand Up @@ -89,6 +95,39 @@ resource "coder_script" "claude_code" {
coder exp mcp configure claude-code ${var.folder}
fi

# Handle terminal multiplexer selection (tmux or screen)
if [ "${var.experiment_use_tmux}" = "true" ] && [ "${var.experiment_use_screen}" = "true" ]; then
echo "Error: Both experiment_use_tmux and experiment_use_screen cannot be true simultaneously."
echo "Please set only one of them to true."
exit 1
fi

# Run with tmux if enabled
if [ "${var.experiment_use_tmux}" = "true" ]; then
echo "Running Claude Code in the background with tmux..."

# Check if tmux is installed
if ! command_exists tmux; then
echo "Error: tmux is not installed. Please install tmux manually."
exit 1
fi

touch "$HOME/.claude-code.log"

export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# Create a new tmux session in detached mode
tmux new-session -d -s claude-code -c ${var.folder} "claude"

# Send the prompt to the tmux session if needed
if [ -n "$CODER_MCP_CLAUDE_TASK_PROMPT" ]; then
tmux send-keys -t claude-code "$CODER_MCP_CLAUDE_TASK_PROMPT"
sleep 5
tmux send-keys -t claude-code Enter
fi
fi

# Run with screen if enabled
if [ "${var.experiment_use_screen}" = "true" ]; then
echo "Running Claude Code in the background..."
Expand Down Expand Up @@ -149,20 +188,27 @@ resource "coder_app" "claude_code" {
#!/bin/bash
set -e

if [ "${var.experiment_use_screen}" = "true" ]; then
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

if [ "${var.experiment_use_tmux}" = "true" ]; then
if tmux has-session -t claude-code 2>/dev/null; then
echo "Attaching to existing Claude Code tmux session." | tee -a "$HOME/.claude-code.log"
tmux attach-session -t claude-code
else
echo "Starting a new Claude Code tmux session." | tee -a "$HOME/.claude-code.log"
tmux new-session -s claude-code -c ${var.folder} "claude --dangerously-skip-permissions | tee -a \"$HOME/.claude-code.log\"; exec bash"
fi
elif [ "${var.experiment_use_screen}" = "true" ]; then
if screen -list | grep -q "claude-code"; then
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
echo "Attaching to existing Claude Code session." | tee -a "$HOME/.claude-code.log"
echo "Attaching to existing Claude Code screen session." | tee -a "$HOME/.claude-code.log"
screen -xRR claude-code
else
echo "Starting a new Claude Code session." | tee -a "$HOME/.claude-code.log"
screen -S claude-code bash -c 'export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; claude --dangerously-skip-permissions | tee -a "$HOME/.claude-code.log"; exec bash'
echo "Starting a new Claude Code screen session." | tee -a "$HOME/.claude-code.log"
screen -S claude-code bash -c 'claude --dangerously-skip-permissions | tee -a "$HOME/.claude-code.log"; exec bash'
fi
else
cd ${var.folder}
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
claude
fi
EOT
Expand Down