@@ -38,6 +38,7 @@ locals {
3838 repo_base_dir = data. coder_parameter . repo_base_dir . value == " ~" ? " /home/coder" : replace (data. coder_parameter . repo_base_dir . value , " /^~\\ //" , " /home/coder/" )
3939 repo_dir = replace (try (module. git-clone [0 ]. repo_dir , " " ), " /^~\\ //" , " /home/coder/" )
4040 container_name = " coder-${ data . coder_workspace_owner . me . name } -${ lower (data. coder_workspace . me . name )} "
41+ has_ai_prompt = data. coder_parameter . ai_prompt . value != " "
4142}
4243
4344data "coder_workspace_preset" "cpt" {
@@ -150,6 +151,13 @@ data "coder_parameter" "image_type" {
150151 }
151152}
152153
154+ variable "anthropic_api_key" {
155+ type = string
156+ description = " The API key used to authenticate with the Anthropic API."
157+ default = " "
158+ sensitive = true
159+ }
160+
153161locals {
154162 default_regions = {
155163 // keys should match group names
@@ -242,6 +250,14 @@ data "coder_parameter" "devcontainer_autostart" {
242250 mutable = true
243251}
244252
253+ data "coder_parameter" "ai_prompt" {
254+ type = " string"
255+ name = " AI Prompt"
256+ default = " "
257+ description = " Prompt for Claude Code"
258+ mutable = false
259+ }
260+
245261provider "docker" {
246262 host = lookup (local. docker_host , data. coder_parameter . region . value )
247263}
@@ -380,6 +396,24 @@ module "devcontainers-cli" {
380396 agent_id = coder_agent. dev . id
381397}
382398
399+ module "claude-code" {
400+ count = local. has_ai_prompt ? data. coder_workspace . me . start_count : 0
401+ source = " dev.registry.coder.com/coder/claude-code/coder"
402+ version = " ~>2.0"
403+ agent_id = coder_agent. dev . id
404+ folder = local. repo_dir
405+ install_claude_code = true
406+ claude_code_version = " latest"
407+ order = 999
408+
409+ experiment_report_tasks = true
410+ experiment_post_install_script = <<- EOT
411+ claude mcp add playwright npx -- @playwright/mcp@latest --headless --isolated --no-sandbox
412+ claude mcp add desktop-commander npx -- @wonderwhy-er/desktop-commander@latest
413+ EOT
414+ }
415+
416+
383417resource "coder_agent" "dev" {
384418 arch = " amd64"
385419 os = " linux"
@@ -710,4 +744,129 @@ resource "coder_metadata" "container_info" {
710744 key = " region"
711745 value = data. coder_parameter . region . option [index (data. coder_parameter . region . option . * . value , data. coder_parameter . region . value )]. name
712746 }
747+ item {
748+ key = " ai_task"
749+ value = local. has_ai_prompt ? " yes" : " no"
750+ }
751+ }
752+
753+ resource "coder_env" "claude_system_prompt" {
754+ count = local. has_ai_prompt ? data. coder_workspace . me . start_count : 0
755+ agent_id = coder_agent. dev . id
756+ name = " CODER_MCP_CLAUDE_SYSTEM_PROMPT"
757+ value = <<- EOT
758+ <system>
759+ -- Framing --
760+ You are a helpful Coding assistant. Aim to autonomously investigate
761+ and solve issues the user gives you and test your work, whenever possible.
762+
763+ Avoid shortcuts like mocking tests. When you get stuck, you can ask the user
764+ but opt for autonomy.
765+
766+ -- Tool Selection --
767+ - coder_report_task: providing status updates or requesting user input.
768+ - playwright: previewing your changes after you made them
769+ to confirm it worked as expected
770+ - desktop-commander - use only for commands that keep running
771+ (servers, dev watchers, GUI apps).
772+ - Built-in tools - use for everything else:
773+ (file operations, git commands, builds & installs, one-off shell commands)
774+
775+ Remember this decision rule:
776+ - Stays running? → desktop-commander
777+ - Finishes immediately? → built-in tools
778+
779+ -- Task Reporting --
780+ Report all tasks to Coder, following these EXACT guidelines:
781+ 1. Be granular. If you are investigating with multiple steps, report each step
782+ to coder.
783+ 2. IMMEDIATELY report status after receiving ANY user message
784+ 3. Use "state": "working" when actively processing WITHOUT needing
785+ additional user input
786+ 4. Use "state": "complete" only when finished with a task
787+ 5. Use "state": "failure" when you need ANY user input, lack sufficient
788+ details, or encounter blockers
789+
790+ In your summary:
791+ - Be specific about what you're doing
792+ - Clearly indicate what information you need from the user when in
793+ "failure" state
794+ - Keep it under 160 characters
795+ - Make it actionable
796+
797+ -- Context --
798+ There is an existing application in the current directory.
799+ Be sure to read CLAUDE.md before making any changes.
800+
801+ This is a real-world production application. As such, make sure to think carefully, use TODO lists, and plan carefully before making changes.
802+ </system>
803+ EOT
804+ }
805+
806+ resource "coder_env" "claude_task_prompt" {
807+ count = local. has_ai_prompt ? data. coder_workspace . me . start_count : 0
808+ agent_id = coder_agent. dev . id
809+ name = " CODER_MCP_CLAUDE_TASK_PROMPT"
810+ value = data. coder_parameter . ai_prompt . value
811+ }
812+
813+ resource "coder_env" "anthropic_api_key" {
814+ count = local. has_ai_prompt ? data. coder_workspace . me . start_count : 0
815+ agent_id = coder_agent. dev . id
816+ name = " ANTHROPIC_API_KEY"
817+ value = var. anthropic_api_key
818+ }
819+
820+ resource "coder_app" "develop_sh" {
821+ count = local. has_ai_prompt ? data. coder_workspace . me . start_count : 0
822+ agent_id = coder_agent. dev . id
823+ slug = " develop-sh"
824+ display_name = " develop.sh"
825+ icon = " ${ data . coder_workspace . me . access_url } /emojis/1f4bb.png" // 💻
826+ command = " screen -x develop_sh"
827+ share = " authenticated"
828+ subdomain = true
829+ open_in = " tab"
830+ order = 0
831+ }
832+
833+ resource "coder_script" "develop_sh" {
834+ count = local. has_ai_prompt ? data. coder_workspace . me . start_count : 0
835+ display_name = " develop.sh"
836+ agent_id = coder_agent. dev . id
837+ run_on_start = true
838+ start_blocks_login = false
839+ icon = " ${ data . coder_workspace . me . access_url } /emojis/1f4bb.png" // 💻
840+ script = <<- EOT
841+ #!/usr/bin/env bash
842+ set -eux -o pipefail
843+
844+ # Wait for the agent startup script to finish.
845+ for attempt in {1..60}; do
846+ if [[ -f /tmp/.coder-startup-script.done ]]; then
847+ break
848+ fi
849+ echo "Waiting for agent startup script to finish... ($attempt/60)"
850+ sleep 10
851+ done
852+ cd "${ local . repo_dir } " && screen -dmS develop_sh /bin/sh -c 'while true; do ./scripts/develop.sh --; echo "develop.sh exited with code $? restarting in 30s"; sleep 30; done'
853+ EOT
854+ }
855+
856+ resource "coder_app" "preview" {
857+ count = local. has_ai_prompt ? data. coder_workspace . me . start_count : 0
858+ agent_id = coder_agent. dev . id
859+ slug = " preview"
860+ display_name = " Preview"
861+ icon = " ${ data . coder_workspace . me . access_url } /emojis/1f50e.png" // 🔎
862+ url = " http://localhost:8080"
863+ share = " authenticated"
864+ subdomain = true
865+ open_in = " tab"
866+ order = 1
867+ healthcheck {
868+ url = " http://localhost:8080/healthz"
869+ interval = 5
870+ threshold = 15
871+ }
713872}
0 commit comments