Skip to content

Commit f10f5a4

Browse files
committed
chore: add sample data
1 parent a00a9ce commit f10f5a4

File tree

9 files changed

+488
-5
lines changed

9 files changed

+488
-5
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,6 @@ dist
135135
.yarn/install-state.gz
136136
.pnp.*
137137

138-
# Script output
138+
# Things needed for CI
139139
/readmevalidation
140+
/readmevalidation-git

cmd/readmevalidation/coderResources.go

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ import (
1212
"coder.com/coder-registry/cmd/github"
1313
)
1414

15+
// dummyGitDirectory is the directory that a full version of the Registry will
16+
// be cloned into during CI. The CI needs to use Git history to validate
17+
// certain README files, and using the root branch itself (even though it's
18+
// fully equivalent) has a risk of breaking other CI steps when switching
19+
// branches. Better to make a full isolated copy and manipulate that.
20+
const dummyGitDirectory = "./readmevalidation-git"
21+
1522
var supportedResourceTypes = []string{"modules", "templates"}
1623

1724
type coderResourceFrontmatter struct {

cmd/readmevalidation/main.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"coder.com/coder-registry/cmd/github"
1616
"github.com/go-git/go-git/v5"
1717
"github.com/go-git/go-git/v5/plumbing"
18+
"github.com/go-git/go-git/v5/plumbing/transport/http"
1819
"github.com/joho/godotenv"
1920
)
2021

@@ -110,9 +111,9 @@ func main() {
110111
}
111112
fmt.Printf("------ got %d back\n", len(baseRefReadmeFiles))
112113

113-
repo, err := git.PlainOpenWithOptions(".", &git.PlainOpenOptions{
114-
DetectDotGit: false,
115-
EnableDotGitCommonDir: false,
114+
repo, err := git.PlainClone(dummyGitDirectory, true, &git.CloneOptions{
115+
URL: "https://github.com/coder/registry",
116+
Auth: &http.BasicAuth{},
116117
})
117118
if err != nil {
118119
return err
@@ -123,7 +124,6 @@ func main() {
123124
return err
124125
}
125126
activeBranchName := head.Name().Short()
126-
fmt.Println("yeah...")
127127

128128
tree, err := repo.Worktree()
129129
if err != nil {

cmd/readmevalidation/repoStructure.go

+6
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ func validateRegistryDirectory() []error {
7171
problems = append(problems, err)
7272
}
7373

74+
mainTerraformPath := path.Join(dirPath, "main.tf")
75+
_, err = os.Stat(mainTerraformPath)
76+
if err != nil {
77+
problems = append(problems, err)
78+
}
79+
7480
for _, rType := range supportedResourceTypes {
7581
resourcePath := path.Join(dirPath, rType)
7682
if errs := validateCoderResourceSubdirectory(resourcePath); len(errs) != 0 {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
display_name: Claude Code
3+
description: Run Claude Code in your workspace
4+
icon: ../.icons/claude.svg
5+
verified: true
6+
tags: [agent, claude-code]
7+
---
8+
9+
# Claude Code
10+
11+
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.
12+
13+
```tf
14+
module "claude-code" {
15+
source = "registry.coder.com/modules/claude-code/coder"
16+
version = "1.0.31"
17+
agent_id = coder_agent.example.id
18+
folder = "/home/coder"
19+
install_claude_code = true
20+
claude_code_version = "latest"
21+
}
22+
```
23+
24+
## Prerequisites
25+
26+
- Node.js and npm must be installed in your workspace to install Claude Code
27+
- `screen` must be installed in your workspace to run Claude Code in the background
28+
- You must add the [Coder Login](https://registry.coder.com/modules/coder-login) module to your template
29+
30+
The `codercom/oss-dogfood:latest` container image can be used for testing on container-based workspaces.
31+
32+
## Examples
33+
34+
### Run in the background and report tasks (Experimental)
35+
36+
> This functionality is in early access as of Coder v2.21 and is still evolving.
37+
> For now, we recommend testing it in a demo or staging environment,
38+
> rather than deploying to production
39+
>
40+
> Learn more in [the Coder documentation](https://coder.com/docs/tutorials/ai-agents)
41+
>
42+
> Join our [Discord channel](https://discord.gg/coder) or
43+
> [contact us](https://coder.com/contact) to get help or share feedback.
44+
45+
Your workspace must have `screen` installed to use this.
46+
47+
```tf
48+
variable "anthropic_api_key" {
49+
type = string
50+
description = "The Anthropic API key"
51+
sensitive = true
52+
}
53+
54+
module "coder-login" {
55+
count = data.coder_workspace.me.start_count
56+
source = "registry.coder.com/modules/coder-login/coder"
57+
version = "1.0.15"
58+
agent_id = coder_agent.example.id
59+
}
60+
61+
data "coder_parameter" "ai_prompt" {
62+
type = "string"
63+
name = "AI Prompt"
64+
default = ""
65+
description = "Write a prompt for Claude Code"
66+
mutable = true
67+
}
68+
69+
# Set the prompt and system prompt for Claude Code via environment variables
70+
resource "coder_agent" "main" {
71+
# ...
72+
env = {
73+
CODER_MCP_CLAUDE_API_KEY = var.anthropic_api_key # or use a coder_parameter
74+
CODER_MCP_CLAUDE_TASK_PROMPT = data.coder_parameter.ai_prompt.value
75+
CODER_MCP_APP_STATUS_SLUG = "claude-code"
76+
CODER_MCP_CLAUDE_SYSTEM_PROMPT = <<-EOT
77+
You are a helpful assistant that can help with code.
78+
EOT
79+
}
80+
}
81+
82+
module "claude-code" {
83+
count = data.coder_workspace.me.start_count
84+
source = "registry.coder.com/modules/claude-code/coder"
85+
version = "1.0.31"
86+
agent_id = coder_agent.example.id
87+
folder = "/home/coder"
88+
install_claude_code = true
89+
claude_code_version = "0.2.57"
90+
91+
# Enable experimental features
92+
experiment_use_screen = true
93+
experiment_report_tasks = true
94+
}
95+
```
96+
97+
## Run standalone
98+
99+
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.
100+
101+
```tf
102+
module "claude-code" {
103+
source = "registry.coder.com/modules/claude-code/coder"
104+
version = "1.0.31"
105+
agent_id = coder_agent.example.id
106+
folder = "/home/coder"
107+
install_claude_code = true
108+
claude_code_version = "latest"
109+
110+
# Icon is not available in Coder v2.20 and below, so we'll use a custom icon URL
111+
icon = "https://registry.npmmirror.com/@lobehub/icons-static-png/1.24.0/files/dark/claude-color.png"
112+
}
113+
```
+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+
}
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
display_name: Cursor IDE
3+
description: Add a one-click button to launch Cursor IDE
4+
icon: ../.icons/cursor.svg
5+
verified: true
6+
tags: [ide, cursor, helper]
7+
---
8+
9+
# Cursor IDE
10+
11+
Add a button to open any workspace with a single click in Cursor IDE.
12+
13+
Uses the [Coder Remote VS Code Extension](https://github.com/coder/vscode-coder).
14+
15+
```tf
16+
module "cursor" {
17+
count = data.coder_workspace.me.start_count
18+
source = "registry.coder.com/modules/cursor/coder"
19+
version = "1.0.19"
20+
agent_id = coder_agent.example.id
21+
}
22+
```
23+
24+
## Examples
25+
26+
### Open in a specific directory
27+
28+
```tf
29+
module "cursor" {
30+
count = data.coder_workspace.me.start_count
31+
source = "registry.coder.com/modules/cursor/coder"
32+
version = "1.0.19"
33+
agent_id = coder_agent.example.id
34+
folder = "/home/coder/project"
35+
}
36+
```

0 commit comments

Comments
 (0)