Skip to content
This repository was archived by the owner on May 15, 2025. It is now read-only.

Commit d0c1657

Browse files
authored
feat: add claude code and Goose module (#420)
ready
1 parent 8b184eb commit d0c1657

File tree

9 files changed

+629
-121
lines changed

9 files changed

+629
-121
lines changed

.icons/claude.svg

+4
Loading

.icons/goose.svg

+4
Loading

claude-code/README.md

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
display_name: Claude Code
3+
description: Run Claude Code in your workspace
4+
icon: ../.icons/claude.svg
5+
maintainer_github: coder
6+
verified: true
7+
tags: [agent, claude-code]
8+
---
9+
10+
# Claude Code
11+
12+
Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview) agent in your workspace to generate code and perform tasks.
13+
14+
```tf
15+
module "claude-code" {
16+
source = "registry.coder.com/modules/claude-code/coder"
17+
version = "1.0.31"
18+
agent_id = coder_agent.example.id
19+
folder = "/home/coder"
20+
install_claude_code = true
21+
claude_code_version = "latest"
22+
}
23+
```
24+
25+
### Prerequisites
26+
27+
- Node.js and npm must be installed in your workspace to install Claude Code
28+
- `screen` must be installed in your workspace to run Claude Code in the background
29+
- You must add the [Coder Login](https://registry.coder.com/modules/coder-login) module to your template
30+
31+
The `codercom/oss-dogfood:latest` container image can be used for testing on container-based workspaces.
32+
33+
## Examples
34+
35+
### Run in the background and report tasks (Experimental)
36+
37+
> This functionality is in early access and subject to change. Do not run in
38+
> production as it is unstable. Instead, deploy these changes into a demo or
39+
> staging environment.
40+
>
41+
> Join our [Discord channel](https://discord.gg/coder) or
42+
> [contact us](https://coder.com/contact) to get help or share feedback.
43+
44+
Your workspace must have `screen` installed to use this.
45+
46+
```tf
47+
variable "anthropic_api_key" {
48+
type = string
49+
description = "The Anthropic API key"
50+
sensitive = true
51+
}
52+
53+
module "coder-login" {
54+
count = data.coder_workspace.me.start_count
55+
source = "registry.coder.com/modules/coder-login/coder"
56+
version = "1.0.31"
57+
agent_id = coder_agent.example.id
58+
}
59+
60+
data "coder_parameter" "ai_prompt" {
61+
type = "string"
62+
name = "AI Prompt"
63+
default = ""
64+
description = "Write a prompt for Claude Code"
65+
mutable = true
66+
}
67+
68+
# Set the prompt and system prompt for Claude Code via environment variables
69+
resource "coder_agent" "main" {
70+
# ...
71+
env = {
72+
CODER_MCP_CLAUDE_API_KEY = var.anthropic_api_key # or use a coder_parameter
73+
CODER_MCP_CLAUDE_TASK_PROMPT = data.coder_parameter.ai_prompt.value
74+
CODER_MCP_APP_STATUS_SLUG = "claude-code"
75+
CODER_MCP_CLAUDE_SYSTEM_PROMPT = <<-EOT
76+
You are a helpful assistant that can help with code.
77+
EOT
78+
}
79+
}
80+
81+
module "claude-code" {
82+
count = data.coder_workspace.me.start_count
83+
source = "registry.coder.com/modules/claude-code/coder"
84+
version = "1.0.31"
85+
agent_id = coder_agent.example.id
86+
folder = "/home/coder"
87+
install_claude_code = true
88+
claude_code_version = "0.2.57"
89+
90+
# Enable experimental features
91+
experiment_use_screen = true
92+
experiment_report_tasks = true
93+
}
94+
```
95+
96+
## Run standalone
97+
98+
Run Claude Code as a standalone app in your workspace. This will install Claude Code and run it directly without using screen or any task reporting to the Coder UI.
99+
100+
```tf
101+
module "claude-code" {
102+
source = "registry.coder.com/modules/claude-code/coder"
103+
version = "1.0.31"
104+
agent_id = coder_agent.example.id
105+
folder = "/home/coder"
106+
install_claude_code = true
107+
claude_code_version = "latest"
108+
109+
# Icon is not available in Coder v2.20 and below, so we'll use a custom icon URL
110+
icon = "https://registry.npmmirror.com/@lobehub/icons-static-png/1.24.0/files/dark/claude-color.png"
111+
}
112+
```

claude-code/main.tf

+170
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
coder = {
6+
source = "coder/coder"
7+
version = ">= 0.17"
8+
}
9+
}
10+
}
11+
12+
variable "agent_id" {
13+
type = string
14+
description = "The ID of a Coder agent."
15+
}
16+
17+
data "coder_workspace" "me" {}
18+
19+
data "coder_workspace_owner" "me" {}
20+
21+
variable "order" {
22+
type = number
23+
description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)."
24+
default = null
25+
}
26+
27+
variable "icon" {
28+
type = string
29+
description = "The icon to use for the app."
30+
default = "/icon/claude.svg"
31+
}
32+
33+
variable "folder" {
34+
type = string
35+
description = "The folder to run Claude Code in."
36+
default = "/home/coder"
37+
}
38+
39+
variable "install_claude_code" {
40+
type = bool
41+
description = "Whether to install Claude Code."
42+
default = true
43+
}
44+
45+
variable "claude_code_version" {
46+
type = string
47+
description = "The version of Claude Code to install."
48+
default = "latest"
49+
}
50+
51+
variable "experiment_use_screen" {
52+
type = bool
53+
description = "Whether to use screen for running Claude Code in the background."
54+
default = false
55+
}
56+
57+
variable "experiment_report_tasks" {
58+
type = bool
59+
description = "Whether to enable task reporting."
60+
default = false
61+
}
62+
63+
# Install and Initialize Claude Code
64+
resource "coder_script" "claude_code" {
65+
agent_id = var.agent_id
66+
display_name = "Claude Code"
67+
icon = var.icon
68+
script = <<-EOT
69+
#!/bin/bash
70+
set -e
71+
72+
# Function to check if a command exists
73+
command_exists() {
74+
command -v "$1" >/dev/null 2>&1
75+
}
76+
77+
# Install Claude Code if enabled
78+
if [ "${var.install_claude_code}" = "true" ]; then
79+
if ! command_exists npm; then
80+
echo "Error: npm is not installed. Please install Node.js and npm first."
81+
exit 1
82+
fi
83+
echo "Installing Claude Code..."
84+
npm install -g @anthropic-ai/claude-code@${var.claude_code_version}
85+
fi
86+
87+
if [ "${var.experiment_report_tasks}" = "true" ]; then
88+
echo "Configuring Claude Code to report tasks via Coder MCP..."
89+
coder exp mcp configure claude-code ${var.folder}
90+
fi
91+
92+
# Run with screen if enabled
93+
if [ "${var.experiment_use_screen}" = "true" ]; then
94+
echo "Running Claude Code in the background..."
95+
96+
# Check if screen is installed
97+
if ! command_exists screen; then
98+
echo "Error: screen is not installed. Please install screen manually."
99+
exit 1
100+
fi
101+
102+
touch "$HOME/.claude-code.log"
103+
104+
# Ensure the screenrc exists
105+
if [ ! -f "$HOME/.screenrc" ]; then
106+
echo "Creating ~/.screenrc and adding multiuser settings..." | tee -a "$HOME/.claude-code.log"
107+
echo -e "multiuser on\nacladd $(whoami)" > "$HOME/.screenrc"
108+
fi
109+
110+
if ! grep -q "^multiuser on$" "$HOME/.screenrc"; then
111+
echo "Adding 'multiuser on' to ~/.screenrc..." | tee -a "$HOME/.claude-code.log"
112+
echo "multiuser on" >> "$HOME/.screenrc"
113+
fi
114+
115+
if ! grep -q "^acladd $(whoami)$" "$HOME/.screenrc"; then
116+
echo "Adding 'acladd $(whoami)' to ~/.screenrc..." | tee -a "$HOME/.claude-code.log"
117+
echo "acladd $(whoami)" >> "$HOME/.screenrc"
118+
fi
119+
export LANG=en_US.UTF-8
120+
export LC_ALL=en_US.UTF-8
121+
122+
screen -U -dmS claude-code bash -c '
123+
cd ${var.folder}
124+
claude --dangerously-skip-permissions | tee -a "$HOME/.claude-code.log"
125+
exec bash
126+
'
127+
# Extremely hacky way to send the prompt to the screen session
128+
# This will be fixed in the future, but `claude` was not sending MCP
129+
# tasks when an initial prompt is provided.
130+
screen -S claude-code -X stuff "$CODER_MCP_CLAUDE_TASK_PROMPT"
131+
sleep 5
132+
screen -S claude-code -X stuff "^M"
133+
else
134+
# Check if claude is installed before running
135+
if ! command_exists claude; then
136+
echo "Error: Claude Code is not installed. Please enable install_claude_code or install it manually."
137+
exit 1
138+
fi
139+
fi
140+
EOT
141+
run_on_start = true
142+
}
143+
144+
resource "coder_app" "claude_code" {
145+
slug = "claude-code"
146+
display_name = "Claude Code"
147+
agent_id = var.agent_id
148+
command = <<-EOT
149+
#!/bin/bash
150+
set -e
151+
152+
if [ "${var.experiment_use_screen}" = "true" ]; then
153+
if screen -list | grep -q "claude-code"; then
154+
export LANG=en_US.UTF-8
155+
export LC_ALL=en_US.UTF-8
156+
echo "Attaching to existing Claude Code session." | tee -a "$HOME/.claude-code.log"
157+
screen -xRR claude-code
158+
else
159+
echo "Starting a new Claude Code session." | tee -a "$HOME/.claude-code.log"
160+
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'
161+
fi
162+
else
163+
cd ${var.folder}
164+
export LANG=en_US.UTF-8
165+
export LC_ALL=en_US.UTF-8
166+
claude
167+
fi
168+
EOT
169+
icon = var.icon
170+
}

filebrowser/README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ A file browser for your workspace.
1515
module "filebrowser" {
1616
count = data.coder_workspace.me.start_count
1717
source = "registry.coder.com/modules/filebrowser/coder"
18-
version = "1.0.29"
18+
version = "1.0.31"
1919
agent_id = coder_agent.example.id
2020
}
2121
```
@@ -30,7 +30,7 @@ module "filebrowser" {
3030
module "filebrowser" {
3131
count = data.coder_workspace.me.start_count
3232
source = "registry.coder.com/modules/filebrowser/coder"
33-
version = "1.0.29"
33+
version = "1.0.31"
3434
agent_id = coder_agent.example.id
3535
folder = "/home/coder/project"
3636
}
@@ -42,7 +42,7 @@ module "filebrowser" {
4242
module "filebrowser" {
4343
count = data.coder_workspace.me.start_count
4444
source = "registry.coder.com/modules/filebrowser/coder"
45-
version = "1.0.29"
45+
version = "1.0.31"
4646
agent_id = coder_agent.example.id
4747
database_path = ".config/filebrowser.db"
4848
}
@@ -54,7 +54,7 @@ module "filebrowser" {
5454
module "filebrowser" {
5555
count = data.coder_workspace.me.start_count
5656
source = "registry.coder.com/modules/filebrowser/coder"
57-
version = "1.0.29"
57+
version = "1.0.31"
5858
agent_id = coder_agent.example.id
5959
agent_name = "main"
6060
subdomain = false

0 commit comments

Comments
 (0)